//
//  ViewController.swift
//  HLDesktop
//
//  Created by 子凡 on 2025/4/10.
//

import UIKit
import Photos

//import SDWebImage
import SDWebImageWebPCoder

//import AVFoundation
import AudioToolbox

class ViewController: UIViewController {
//    var alpaBackView: UIImageView!
    
    lazy var scrollPageView: UIScrollView = {
        let scroll = UIScrollView()
        scroll.isScrollEnabled = true
        scroll.isPagingEnabled = true
        scroll.showsHorizontalScrollIndicator = false
        return scroll
    }()
    
    lazy var configButton: UIButton = {
        let button = UIButton()
        button.setImage(UIImage(named: "toolbtn_config@2x.png"), for: .normal)
        return button
    }()
    
    lazy var addAppButton: UIButton = {
        let button = UIButton()
        button.setImage(UIImage(named: "toolbtn_add@2x.png"), for: .normal)
        return button
    }()
    
    lazy var cfgWallButton: ProfileButton = {
        let button = ProfileButton()
        button.setTitle("壁纸", for: .normal)
        button.setTitleColor(.white, for: .normal)
        button.titleLabel?.font = .boldSystemFont(ofSize: 14)
        button.layer.cornerRadius = 13
        button.backgroundColor = prjTitleColor.withAlphaComponent(0.75)
        button.layer.borderColor = UIColor.white.withAlphaComponent(0.5).cgColor
        return button
    }()
    
    lazy var resetPosButton: ProfileButton = {
        let button = ProfileButton()
        button.setTitle("复位", for: .normal)//need.update.to:顶部，底部，左边，右边，上下平分、左右平分，中聚
        button.setTitleColor(.white, for: .normal)
        button.titleLabel?.font = .boldSystemFont(ofSize: 14)
        button.layer.cornerRadius = 13
        button.backgroundColor = prjTitleColor.withAlphaComponent(0.75)
        button.layer.borderColor = UIColor.white.withAlphaComponent(0.5).cgColor
        return button
    }()
    
    lazy var matrixButton: ProfileButton = {
        let button = ProfileButton()
        button.setTitle("对齐", for: .normal)
        button.setTitleColor(.white, for: .normal)
        button.titleLabel?.font = .boldSystemFont(ofSize: 14)
        button.layer.cornerRadius = 13
        button.backgroundColor = prjTitleColor.withAlphaComponent(0.75)
        button.layer.borderColor = UIColor.white.withAlphaComponent(0.5).cgColor
        return button
    }()
    
    lazy var screenSaverButton: ProfileButton = {
        let button = ProfileButton()
        button.setTitle("屏保", for: .normal)
        button.setTitleColor(.white, for: .normal)
        button.titleLabel?.font = .boldSystemFont(ofSize: 14)
        button.layer.cornerRadius = 13
        button.backgroundColor = prjTitleColor.withAlphaComponent(0.75)
        button.layer.borderColor = UIColor.white.withAlphaComponent(0.5).cgColor
        return button
    }()
    
    lazy var topbarView: UIView = {
        let toolview = UIView()
        return toolview
    }()
    
    var expandBackgroundImgView:UIImageView?

    var iPageIndex:Int = 0
    var pageWallList:[UIImageView] = [] //每页(全屏)壁纸View
    var pageWorkList:[UIView] = [] //每页工作区view(放置App图标区域)
    
    var icoLabelList:[[IcoLabel]] = [] //保存每个页面的图标组
    var lineList:[UIView] = []
    
    //当前页解析出来的每个App的Title\scheme\ico\storelink\locate
    var titleSource:[String] = []
    var schemeSource:[String] = []
    var icourlSource:[String] = []
    var storeLinkSource:[String] = []
//    var appLocation:[CGPoint] = []
    
    var isModified = false //本页是否有删除、修改、增加等操作
    var modingApp:IcoLabel? = nil
    
    var isShowed:Bool = false
    
    let appWidth = 72.0
    let appHeight = 84.0
    
    var BasicLinePos:[CGPoint] = [] //基线点，用于自动对齐用(当某图标，离基线很近时自默认设为基线点位)
    
    var hideTopbar:Bool = false
    var hideBottomBar:Bool = true
    
    var batteryView: UIImageView?
    var batteryEmitter: CAEmitterLayer?
    var batteryWave:WaveView?
    var batteryTimer: Timer?
    var batteryLevel: Float { UIDevice.current.batteryLevel }
//    电池电量从0.0（完全放电）到1.0（100％充电）。访问此属性之前，请确保已启用电池监视。如果未启用电池监视，则电池状态为UIDevice.BatteryState.unknown，此属性的值为–1.0。
    var batteryState: UIDevice.BatteryState { UIDevice.current.batteryState }
//    电池状态.unknown/.unplugge未充电/.charging充电中/.full满电
    var popMenu:HLPopMenu?
    
    var leftPopBar:UIView?
    
    var real_Statusbar_height:CGFloat=0 //判断real_Statusbar_height>20为刘海屏
    
//    var player: AVAudioPlayer?
    var _soundID:SystemSoundID = 0
    var led_layer_dot_1:CALayer?
    var led_layer_dot_2:CALayer?
    var clockTimer: Timer?
    var pressHeartLayer:CAEmitterLayer?
    
    var bloom_soundid:SystemSoundID = 0 //AudioServicesPlaySystemSound(self.bloomSound);
    var fold_soundid:SystemSoundID = 0
    var select_soundid:SystemSoundID = 0
    
    deinit {//奇怪，在viewDidLoad初始化过程中，会触发一次deinit
        print("没有循环引用才会触发:MainVC.deinit")
//        stopClockTimer()
//        stopBatteryTimer()
        freePlay()
        SDWebImageManager.shared.imageCache.clear?(with: .all)
//timer去掉循环引用后，或者在此先释放掉timer，在iphoex不会再触发terminateApp
//如果timer有循环引用，且未释放，关闭时会触发terminateApp
//UIApplicationWillTerminateNotification消息是应用在前台,双击Home键,杀掉调用，但是应用在后台,双击Home键, 再终止应用不会被通知
//但是，实没划掉之前App还在前台时，此时只有deinit触发，没有terminateApp；
//如果划掉之前App在后台，此时调试器会认为App被迫止，deinit也不会触发，而是Message from debugger: Terminated due to signal 9
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        real_Statusbar_height = UIDevice.ui_statusBarHeight()
        print("real_Statusbar_height=\(real_Statusbar_height)")
        // Do any additional setup after loading the view.
        self.view.backgroundColor = .systemGroupedBackground
        initView()
        initNoti()
        initLeftBar()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.setNeedsUpdateOfHomeIndicatorAutoHidden()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        if (self.modingApp != nil && !self.topbarView.isHidden){ //从其它页面回来，动画会停掉
            self.stopAppShake(except: self.modingApp!)
            self.modingApp?.enabelEdit()
        }
        isShowed = true
        showBatteryOrNot()
        showProtoclOrNot()

        if let snapshot = self.view.viewWithTag(1023){
            let starsCrush = StarsViewGLAnimator()
            starsCrush.duration = 1.25
            starsCrush.xSmallDiff = -50.0
            starsCrush.xBigDiff = 50.0
            starsCrush.animateCrushView(crushView: snapshot, In: snapshot.superview!)
            if let _ = snapshot.superview{
                snapshot.removeFromSuperview()
            }
        }
                           
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        stopScreenSave() //开启新页面时关闭屏保
        removeBatteryAnimate()//关闭充电动画
    }
    
//同上，还要处理从后台到前台的切换，状态.need.do
    
//MARK: - UI初始化
    func preInitView(){
        self.view.backgroundColor = .systemGroupedBackground
    }
    
    func initView(){
//整个底景
//        self.view.backgroundColor =  UIImage(named: "wall84@2x.jpg")?.imageColor()
        
        let topSpace = UIDevice.ui_navigationFullHeight()
        let bottomSpace = max(UIDevice.ui_safeDistanceBottom(), 15) //iphone8下为0
        let workHeight = screen_H-topSpace-bottomSpace
        view.addSubview(scrollPageView)
        scrollPageView.delegate = self
        scrollPageView.frame = CGRect(x: 0, y: 0, width: screen_W, height: screen_H)
        
        
//延展壁纸(一张壁纸在多个页面显示，每个页面显示壁纸的一部分)
//        let backImgView = UIImageView(frame: CGRect(x: 0, y: 0, width: screen_W*2, height: screen_H))
//        scrollPageView.addSubview(backImgView)
////        backImgView.image = UIImage(named: "test_01@2x.jpg")! //从缓存中取
//        backImgView.contentMode = .scaleAspectFill
//        backImgView.isUserInteractionEnabled = true
//        backImgView.isHidden = true
        
//每个页面自身的壁纸
        let iJG = (screen_W - appWidth * 4.0) / 5.0 //app之前间隔
        var iPageLeft = 0.0
//        let firstLaunch = UserDefaults.standard.bool(forKey: "aiScreen.is.first.luanch")
//        if !firstLaunch{
////首次启动处理,默认2张图片，及添加若干默认快捷项
//        }
        for i in 0 ..< 2{
            let page_1 = UIImageView(frame: CGRect(x: iPageLeft, y: 0, width: screen_W, height: screen_H))
            scrollPageView.addSubview(page_1)
            page_1.contentMode = .scaleAspectFill //不用此模式，图像可以变形；但用此模式，可能宽度超出，需要clipsToBounds
            page_1.isUserInteractionEnabled = true
            page_1.clipsToBounds = true
            pageWallList.append(page_1)
            let wallkey = String(format: "key_wallpaper_for_page_%d", i)
//--------
            func loadHttpDeskWall(at index:Int,_ paperUrl:String,seccondUrl:String?=nil){
                var tmpBkView:UIImageView? = UIImageView(image: UIImage(named: "defaltWall@2x.jpeg"))
                if let tmpImgView = tmpBkView{
                    pageWallList[index].insertSubview(tmpImgView, at: 0) //加载网络图片前，先显示默认图，然后加载完成后再过渡到壁纸
                    tmpImgView.frame = CGRect(x: 0, y: 0, width: screen_W, height: screen_H)
                }
                pageWallList[index].loadImageFrom(imageurl: paperUrl,And: seccondUrl) { [weak self](picUrl) in
                    if picUrl == nil{ //加载网络图片出错
                        self?.pageWallList[index].image = UIImage(named: "defaltWall@2x.jpeg")
                    }
                    UIView.animate(withDuration: 0.75, delay: 0,options: [.curveEaseInOut]) {
                        tmpBkView?.layer.opacity = 0
                    } completion: { finised in
                        tmpBkView?.isHidden = true
                        tmpBkView?.image = nil
                        tmpBkView?.removeFromSuperview()
                        tmpBkView = nil
                    }
                }
            }
//--------------
//!!!原来主要的内存在显示动态壁纸这块占用了很大内存，从30M左右一下子到了280M左右，而这些基本都是SDWebImage的缓存?
            if let paperData = UserDefaults.standard.value(forKey: wallkey) {
                if let papername = paperData as? String{
                    if papername.hasPrefix("http"){
//let testUrl = "https://upload-images.jianshu.io/upload_images/6873388-37b883290280e216.gif"
                        loadHttpDeskWall(at: i,papername)
                    }else{
                        page_1.setImageWithStr(imgurl: papername,defName: "defaltWall@2x.jpeg")
                    }
                }else{//非string，则一定为NSData类型，因为缓存的时候只存储了这2种类型
                    page_1.startGifWithImageData(imgdata: paperData as? NSData) //兼容jpg、gif的data
                }
            }else{
               if 0 == i{
                    loadHttpDeskWall(at: i,"https://upload-images.jianshu.io/upload_images/6873388-9ed2c55f35cc4245.gif",
                                     seccondUrl: "https://note.youdao.com/yws/public/resource/6e06c8156caad8d3af1dc118f742ac34/xmlnote/WEBRESOURCE7fc2fdbdaf3e07fb78feff8ce810d269/154803")
//                    page_1.setImageWithStr(imgurl: "wall27@2x.webp")
                   UserDefaults.standard.set("https://upload-images.jianshu.io/upload_images/6873388-9ed2c55f35cc4245.gif", forKey: wallkey)
                   UserDefaults.standard.synchronize()
                }else{
                    loadHttpDeskWall(at: i,"https://upload-images.jianshu.io/upload_images/6873388-7e7aca3aca7c713b.gif",
                                     seccondUrl: "https://note.youdao.com/yws/public/resource/6e06c8156caad8d3af1dc118f742ac34/xmlnote/WEBRESOURCEf9eb8e92bac0b0742172bb67c73cb427/154801")
//                    page_1.setImageWithStr(imgurl: "wall28@2x.webp")
                    UserDefaults.standard.set("https://upload-images.jianshu.io/upload_images/6873388-7e7aca3aca7c713b.gif", forKey: wallkey)
                    UserDefaults.standard.synchronize()
                }
            }
            
            let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
            page_1.addGestureRecognizer(longPress)
// page_1.setImageWithStr(imgurl: "wall86@2x.jpg")
//！！！奇怪，增加这样后面对page_1设置gif图片，显示正常，如果直接对page_1设置gif图片，会显示成横屏！这是TM为啥？！
//原来是上面读取的默认壁纸是从相册里面选取的图片，所导致的。
//从相册选取的照片虽显示是纵向的，但由于是相机拍摄的默认不是UIImageOrientationUp，故导致之后再设置gif就会变成横向
//所以如果选取相册照片做为壁纸，则对Image要做一个UIImagePNGRepresentation处理
            
            let view_1 = UIView(frame: CGRect(x: 0, y: topSpace, width: screen_W, height: workHeight)) //App图标区域(头部和底部安全区不能放App图标)
            page_1.addSubview(view_1)
            pageWorkList.append(view_1)
            iPageLeft += screen_W
            
//画编辑时对比基准线条
            var halfJG = appHeight / 4 //竖向线条间隔
            var lineTop = 0.0
            var iFlag = 0
            var lineColor:UIColor = prjTitleColor
            var yPosList:[CGFloat] = []
            if 0 == BasicLinePos.count{
                yPosList.append(lineTop)
            }
            while (lineTop < workHeight){
    //横线
                let lineView = UIView(frame: CGRect(x: 0, y: lineTop, width: screen_W, height: 0.5))
                view_1.addSubview(lineView)
                lineList.append(lineView)
                lineView.isHidden = true
                lineView.addDashdeBorderLayer(color: lineColor, lineWidth: 0.5)
                iFlag += 1
                if iFlag % 5 == 0{
                    lineTop += iJG
                    lineColor = prjTitleColor
                    
                    if lineTop < workHeight && lineTop + 2*appHeight > workHeight{
//判断是不是底部最后一行，与上面的行稍微隔开一点，以视为快捷区域
                        lineTop = workHeight - appHeight - 2
                        lineColor = .red
                    }
                    
                    if (0 == BasicLinePos.count) && (lineTop + appHeight <= workHeight){
                        yPosList.append(lineTop)
                    }

                }else{
                    lineTop += halfJG
                    lineColor = .white
                }
            }
            
            iFlag = 0
            halfJG = appWidth/3.0
            var lineLeft = iJG
            lineColor = prjTitleColor
            var xPosList:[CGFloat] = []
            if 0 == BasicLinePos.count{
                xPosList.append(lineLeft)
            }
            while(lineLeft<screen_W){
    //竖线
                let lineView = UIView(frame: CGRect(x:lineLeft, y: 0, width: 0.5, height: workHeight))
                view_1.addSubview(lineView)
                lineList.append(lineView)
                lineView.isHidden = true
                lineView.addDashdeBorderLayer(color: lineColor, lineWidth: 0.5)
                iFlag += 1
                if iFlag % 4 == 0{
                    lineLeft += iJG
                    lineColor = prjTitleColor
                    if 0 == BasicLinePos.count && lineLeft+appWidth <= screen_W{
                        xPosList.append(lineLeft)
                    }
                }else{
                    lineLeft += halfJG
                    lineColor = .white
                }
            }
            
            if 0 == BasicLinePos.count{ //每页都一样
                for i in 0 ..< xPosList.count{
                    for j in 0 ..< yPosList.count{
                        let tmpPoint = CGPoint(x: xPosList[i], y: yPosList[j])
                        BasicLinePos.append(tmpPoint) //默认每个基线的左上角点，App的frame的左上角与此对齐即可
                    }
                }
            }
        }
        
        scrollPageView.contentSize = CGSize(width: iPageLeft, height: screen_H)
        
        for i in 0 ..< pageWallList.count{
            let tmpBatteryBackView = UIView(frame: CGRect(x: 0, y: 0, width: screen_W, height: screen_H))
            pageWallList[i].insertSubview(tmpBatteryBackView, at: 0)
            tmpBatteryBackView.tag = 1990+i
        }
        
//顶部工具栏
        self.initTopToolbar()
        
//显示首页桌面图标
        initPage()
        showToolButton(0 == icoLabelList[iPageIndex].count)
        
    }

    func initTopToolbar(){
        let iTopJG = 10.0
        let iBtnHeight = 26.0
        let iBtnWidth = 54.0
        let iOKHeight = 36.0
        let topSpace = UIDevice.ui_navigationFullHeight()
        
        view.addSubview(topbarView)
        topbarView.frame = CGRect(x: 0, y: topSpace-iTopJG-iOKHeight, width: screen_W, height: iTopJG+iOKHeight)
//右完成
        topbarView.addSubview(self.configButton)
        self.configButton.frame = CGRect(x: screen_W-15-iOKHeight, y: 0, width: iOKHeight, height: iOKHeight)
        self.configButton.addActionWithBlock { [weak self](sender) in
            self?.hideTopbar = false
            self?.setNeedsStatusBarAppearanceUpdate()
//            UIApplication.shared.isIdleTimerDisabled = false //可以自动锁屏
//            UIApplication.shared.isIdleTimerDisabled = true //阻止自动锁屏
            Vibrations.heavy.vibrate()
            self?.showPopmenu()
        }
//左添加
        topbarView.addSubview(self.addAppButton)
        self.addAppButton.frame = CGRect(x: 15, y: 0, width: iOKHeight, height: iOKHeight)
        self.addAppButton.addActionWithBlock { [weak self](sender) in
            Vibrations.medium.vibrate()
            self?.pressAddButton(sender)
        }
        
        let btnJG = min((screen_W - iOKHeight*2 - iBtnWidth*4) / 5.0, 10)
//默认排列(need.update:顶聚、底聚、左聚、右聚、中间聚、上下分、左右分)
        topbarView.addSubview(self.resetPosButton)
        self.resetPosButton.frame = CGRect(x: screen_W/2 - btnJG/2 - iBtnWidth, y: iOKHeight - iBtnHeight, width: iBtnWidth, height: iBtnHeight)
        self.resetPosButton.addActionWithBlock { [weak self](sender) in
            self?.hideTopbar = false
            self?.setNeedsStatusBarAppearanceUpdate()
            Vibrations.light.vibrate()
            if let btn = sender as? ProfileButton{
                btn.animateTouchUpInside {[weak self] in
                    if let self = self{
                        if self.icoLabelList.count > self.iPageIndex && self.icoLabelList[self.iPageIndex].count>0{
                            self.alertMessage("复位图标", message: "确定要按系统默认样式，排列本页图标的位置么？",iRed: true, okBlock: {
                                self.doResetIcoPosition()
                            })
                        }
                        else{
                            Vibrations.error.vibrate()
                            self.view.showToast("您尚未添加快捷项到Ai桌面")
                        }
                    }
                }
            }
        }
//基线对齐
        topbarView.addSubview(self.matrixButton)
        self.matrixButton.frame = CGRect(x: resetPosButton.frame.minX - btnJG - iBtnWidth, y: iOKHeight - iBtnHeight, width: iBtnWidth, height: iBtnHeight)
        self.matrixButton.addActionWithBlock { [weak self](sender) in
            self?.hideTopbar = false
            self?.setNeedsStatusBarAppearanceUpdate()
            Vibrations.light.vibrate()
            if let btn = sender as? ProfileButton{
                btn.animateTouchUpInside {[weak self] in
                    if let self = self{
                        if self.icoLabelList.count > self.iPageIndex && self.icoLabelList[self.iPageIndex].count>0{
                            self.doAutoMatrix()
                        }else{
                            Vibrations.error.vibrate()
                            self.view.showToast("您尚未添加快捷项到Ai桌面")
                        }
                    }
                }
            }
        }
//壁纸
        topbarView.addSubview(self.cfgWallButton)
        self.cfgWallButton.frame = CGRect(x: screen_W/2 + btnJG/2, y: iOKHeight - iBtnHeight, width: iBtnWidth, height: iBtnHeight)
        self.cfgWallButton.addActionWithBlock { [weak self](sender) in
            self?.hideTopbar = false
            self?.setNeedsStatusBarAppearanceUpdate()
            Vibrations.light.vibrate()
            if let btn = sender as? ProfileButton{
                btn.animateTouchUpInside {[weak self] in
                    self?.showWallPaperSelectDlg(sender)
                }
            }
        }
//屏保
        topbarView.addSubview(screenSaverButton)
        screenSaverButton.frame = CGRect(x: cfgWallButton.frame.maxX + btnJG, y: iOKHeight - iBtnHeight, width: iBtnWidth, height: iBtnHeight)
        screenSaverButton.addActionWithBlock { [weak self](sender) in
            Vibrations.light.vibrate()
            if let btn = sender as? ProfileButton{
                btn.animateTouchUpInside {[weak self] in
                    if self?.getSaverUrl() != nil {
                        self?.tapBackView()
                        self?.stopScreenSave()
                        self?.doShowSaver()
                    }else{
                        Vibrations.error.vibrate()
                        self?.view.showToast("请在“壁纸->动态壁纸”中，先设置屏保")
                    }
                }
            }
        }
    }
    
//MARK: - 点击和长按页面
    @objc func handlePress(_ press: UITapGestureRecognizer){
        let pos = press.location(in: self.view)
        Vibrations.selection.vibrate()
        let rippleSize = CGSize(width: 60, height: 60)
        let rippleColor = prjTitleColor.withAlphaComponent(0.75)
        self.view.addRippleEffect(rippleSize: rippleSize, position: pos, color: rippleColor, duration: CFTimeInterval(0.25))
        if let _ = self.view.viewWithTag(1518){
            self.cancelLeftBarItems()
        }
        tapBackView()
    }
    
    @objc func handleLongPress(_ longPress: UILongPressGestureRecognizer) {
        if longPress.state == .began {
//如果是非编辑状态，则将所有App置为可编辑状态
            if hasIcoLabelInCurrentPage(){
                Vibrations.success.vibrate()
                doLongTapIcoLabel(nil)
                self.shakeOtherApps()
                
                let pos = longPress.location(in: self.view)
                showPressCirlceHeart(1,pos)
            }
        }else if longPress.state == .ended{
//            NSLog("longPress.ended")
        }else if longPress.state == .changed{
//            NSLog("longPress.changed")
        }else if longPress.state == .cancelled{
//            NSLog("longPress.cancelled")
        }
    }
    
    func hasIcoLabelInCurrentPage()->Bool{
        if icoLabelList.count>iPageIndex && icoLabelList[iPageIndex].count > 0{
            return true
        }else{
            return false
        }
    }
    
    func tapBackView(){
        self.hideTopbar = false
        self.setNeedsStatusBarAppearanceUpdate()
        
        scrollPageView.isScrollEnabled = true
        self.hideAddGuide()
        removeMovingBackView()
        if hasIcoLabelInCurrentPage(){
            showToolButton(false)
            self.stopAppShake(except: nil)
        }else{
            showToolButton(true)
            showAddButtonGuide()
        }
        showMoveLine(false)
        if isModified{
            recordAppData()
        }
        
        isModified = false
        showScreenSaver()//重新计时屏保
    }
    
    func hideAddGuide(){
        if let tipView = view.viewWithTag(2000){
            let btnframe = addAppButton.frame
            let iTop = topbarView.frame.minY + btnframe.maxY
            UIView.animate(withDuration: 0.25, delay: 0, options: [.curveEaseInOut], animations: {
                tipView.frame = CGRect(x: btnframe.maxX, y:iTop, width: 0, height: 0)
            } ,completion:{ finished in
                tipView.removeFromSuperview()
            })
        }
    }
    
    func showAddButtonGuide(){
        if !isShowed {
            return
        }
        
        let btnframe = addAppButton.frame
        let dlgWidth = 220.0
        let dlgHeight = 80.0
        let iTop = topbarView.frame.minY + btnframe.maxY
        let backView = UIView(frame: CGRect(x: btnframe.maxX, y:iTop, width: 2.2, height: 0.8))
        view.addSubview(backView)
        backView.tag = 2000
        backView.clipsToBounds = true
//画三角箭头
        let layer=CAShapeLayer()
        let path=UIBezierPath()
        path.move(to: CGPoint(x: 0, y: 0))
        path.addLine(to: CGPoint(x: 20, y: 50))
        path.addLine(to: CGPoint(x: 80, y: 20))
        layer.path=path.cgPath
        layer.fillColor = UIColor.systemGroupedBackground.cgColor
        backView.layer.addSublayer(layer)
        
        
        let tipView = UIView(frame: CGRect(x: 10, y: 10, width: dlgWidth-20, height:dlgHeight-20))
        backView.addSubview(tipView)
        tipView.backgroundColor = .systemGroupedBackground
        tipView.setShadow(shadowColor: .systemBackground, offset: CGSize(width: 5, height: 5), opacity: 0.45, radius: 10)
        let tipLabel = UILabel(frame: CGRect(x: 10, y: 5, width: dlgWidth-20-20, height: dlgHeight-20-10))
        tipView.addSubview(tipLabel)
        tipLabel.text = String(format: "开始添加Ai启动项\n打造属于你的Ai桌面吧！")
        tipLabel.textColor = .label
        tipLabel.font = .systemFont(ofSize: 16)
        tipLabel.numberOfLines = 0
        
        UIView.animate(withDuration: 0.5, delay: 0.25, options: [.curveEaseInOut]) {
            backView.frame = CGRect(x: btnframe.maxX, y:iTop, width: dlgWidth, height: dlgHeight)
        }

    }
    
    func showMoveLine(_ flag:Bool){
        for line in lineList {
            line.isHidden = !flag
        }
    }
    
}


//MARK: - 翻页
extension ViewController:UIScrollViewDelegate{
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
//        print("scrollViewDidEndDecelerating:\(scrollView.contentOffset.x)")
        if scrollView.contentOffset.x < screen_W {
            showCurrentPage(0)
        }else{
            showCurrentPage(1)
        }
        self.tapBackView()
    }
    
//    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
//        print("scrollViewDidEndDragging:\(scrollView.contentOffset.x)")
//    }
    
    func initPage(){
        icoLabelList.removeAll()
        for ipage in 0 ..< 2{
            //每次使用alanizyAppItem前都先清除缓存
            schemeSource.removeAll()
            titleSource.removeAll()
            icourlSource.removeAll()
            storeLinkSource.removeAll()
            
            //读取及解析本页App信息
            let keyList = ["aiScreen.App.page1.data","aiScreen.App.page2.data","aiScreen.App.page3.data","aiScreen.App.page4.data","aiScreen.App.page5.data"]
            let sourceList = UserDefaults.standard.array(forKey: keyList[ipage])
            let locateList = UserDefaults.standard.array(forKey: keyList[ipage] + ".location")
            if sourceList != nil && sourceList!.count > 0{
                for perList in sourceList! {
                    let tmpStr = perList as! String
                    let arr = tmpStr.components(separatedBy: "&|&")
                    let _ = alanizyAppItem(arr: arr)
                }
            }
            
            //创建本页App图标
            var iTop = 0.0
            var iCol = 0
            let iJG = (screen_W - appWidth * 4.0) / 5.0 //app之前间隔
            var tmpAppList:[IcoLabel] = []
            for i in 0 ..< titleSource.count{
                var isError = true
                if locateList != nil && locateList!.count == titleSource.count{
                    let pointStr = locateList![i] as! String
                    let tmpArr = pointStr.components(separatedBy: "&")
                    if 2 == tmpArr.count{
                        let pointX = tmpArr[0]
                        let pointY = tmpArr[1]
                        if let d_x = Double(pointX), let d_y = Double(pointY){
                            if let tmpIco = createAppIcoLabelAt(index: i, point: CGPoint(x: d_x, y: d_y),InPage: ipage){
                                tmpIco.lastPage = ipage
                                tmpAppList.append(tmpIco)
                            }
                            isError = false
                        }
                    }
                }
                
                if isError{ //没有x，y坐标，则默认排列位置
                    let locate_x = Double(iCol+1) * iJG + Double(iCol) * appWidth
                    let locate_y = iTop
                    if let tmpIco = createAppIcoLabelAt(index: i, point: CGPoint(x: locate_x, y: locate_y),InPage: ipage){
                        tmpAppList.append(tmpIco)
                    }
                }
                
                iCol += 1
                if iCol % 4 == 0{
                    iTop = iTop + appHeight + iJG
                    iCol = 0
                }
            }
            
            if tmpAppList.count != titleSource.count{
                print("initpage.err.not.same.count")
            }
            icoLabelList.append(tmpAppList)
        }

    }
    
    
    func showCurrentPage(_ ipage:Int){
        if ipage != iPageIndex{
            iPageIndex = ipage
            showBatteryOrNot()//切换充电页面
            showScreenSaver() //重新计时屏保
            self.initLeftBar()
        }
    }
    
}

//MARK: - 将字符数据组解析成当前页面数据&生成本页App图标
extension ViewController{
    func alanizyAppItem(arr:[String])->Bool{
        if arr.count >= 3 { //3-5 url=xxx[&path=xx][&|&storelink=xx]&|&title=xx&|&icon=xxx
            if 3 == arr.count{
                let tmpScheme = (arr[0] as NSString).substring(from: 4) as String
                schemeSource.append(tmpScheme)//url=hilink://
                let tmpTitle = (arr[1] as NSString).substring(from: 6) as String
                titleSource.append(tmpTitle)  //title=德施曼智能
                let tmpIco = (arr[2] as NSString).substring(from: 5) as String
                icourlSource.append(tmpIco) //icon=https://a-1251679148.file.myqcloud.com/api/icon/ap3/mihome.png
                storeLinkSource.append("")
            }else{//4 or 5
                let lastIndex = arr.count - 1
                let tmpIco = (arr[lastIndex] as NSString).substring(from: 5) as String
                icourlSource.append(tmpIco)
                let tmpTitle = (arr[lastIndex-1] as NSString).substring(from: 6) as String
                titleSource.append(tmpTitle)
                
                let tmpScheme = (arr[0] as NSString).substring(from: 4) as String
                if arr[1].hasPrefix("storelink="){//此种情况一般为arr.count=4
                    let storelink = (arr[1] as NSString).substring(from: "storelink=".count) as String
                    storeLinkSource.append(storelink)
                    schemeSource.append(tmpScheme)//说明只有4个，第1个即为url
                }else{
                    schemeSource.append(tmpScheme + "&" + arr[1])//说arr[1]为url的一部分,兼容旧数据结构
                    if arr[2].hasPrefix("storelink="){ //一般为arr.count=5,继续判断是否有storelink
                        let storelink = (arr[2] as NSString).substring(from: "storelink=".count) as String
                        storeLinkSource.append(storelink)
                    }else{
                        storeLinkSource.append("") //为arr.count=4，且第2个不是storelink而是url的一部分
                    }
                }
            }
            return true
        }
        return false
    }
    
    func createAppIcoLabelAt(index:Int,point:CGPoint,InPage:Int) -> IcoLabel?{
        let ico_1 = IcoLabel(frame: CGRect(x: point.x, y: point.y, width: appWidth, height: appHeight))
        pageWorkList[InPage].addSubview(ico_1)
        ico_1.setImage(imgName: icourlSource[index])
        ico_1.setTitle(title: titleSource[index])
        ico_1.setAppBid(bid: schemeSource[index]) //以appBid为唯一标识，进行删除或更新
        ico_1.setStoreLink(link: storeLinkSource[index])
        ico_1.didSeletedBlock = {[weak self] in
            self?.doLongTapIcoLabel(ico_1)
        }
        ico_1.didTapBlock = {[weak self] in
            //点击图标打开对应的App
            self?.tapRunApp(sender: ico_1)
        }
        ico_1.doModiBlock = {[weak self] in
            self?.modiApp(urlscheme: ico_1.appBid())
        }
        ico_1.doDeleteBlock = {[weak self] in
            self?.alertMessage("删除快捷图标", message: "确定要删除此快捷图标么？", okBlock:  {
                self?.deleteApp(urlscheme: ico_1.appBid())
            })
        }
        ico_1.touchStateBlock = { [weak self](state) in
            //0->end(cancel),1-begin,2->beginmove,3-moving
            if 0 == state{ //移动结事，将App加回到当前页桌面
                self?.moveAppOver(sender: ico_1)
            }else if 2 == state{//首次开始移动，将App加到临时层
                self?.moveAppBegin(sender: ico_1)
            }else if 3 == state{//判断是否到了边界，如到了边界，则触发翻页
                self?.movingApp(sender: ico_1)
            }
        }

        return ico_1
    }
}

//MARK: - 顶部toolbar
extension ViewController{
    func showToolButton(_ flag:Bool){
        self.topbarView.isHidden = !flag
    }
    
//复位排列
    func doResetIcoPosition(){
        var iTop = 0.0
        var iCol = 0
        let iJG = (screen_W - appWidth * 4.0) / 5.0 //app之前间隔
        if icoLabelList.count > iPageIndex{
            for i in 0 ..< icoLabelList[iPageIndex].count{
                let locate_x = Double(iCol+1) * iJG + Double(iCol) * appWidth
                let locate_y = iTop
                //            appLocation[i] = CGPoint(x: locate_x, y: locate_y)
                icoLabelList[iPageIndex][i].frame.origin = CGPoint(x: locate_x, y: locate_y) //appLocation[i]
                iCol += 1
                if iCol % 4 == 0{
                    iTop = iTop + appHeight + iJG
                    iCol = 0
                }
            }
        }
        recordAppData()
        
        self.view.showToast("已复位到默认排列位置!")
    }
        
//基线对齐
    func doAutoMatrix(isBottom:Bool=false){
        let halfJG_H = 2*(appWidth / 3.0)
        let halfJG_V = 2*(appHeight / 4.0) //1格之内都可以对齐，太大则需用户手动拖放
        var hasModi = false
        if icoLabelList.count > iPageIndex{
            for perIco in icoLabelList[iPageIndex]{
                let perPoint = perIco.frame.origin
                for j in 0 ..< BasicLinePos.count{
                    let xJG = abs(perPoint.x - BasicLinePos[j].x)
                    let yJG = abs(perPoint.y - BasicLinePos[j].y)
                    if (xJG > 1.5 || yJG > 1.5) && xJG < halfJG_H  && yJG < halfJG_V{
                        perIco.frame = CGRect(x: BasicLinePos[j].x, y: BasicLinePos[j].y+1, width: perIco.bounds.width, height: perIco.bounds.height)
                        hasModi = true
                        break
                    }
                }
            }
        }
        if hasModi{
            recordAppData()
        }
        
        self.view.showToast("已按基准线对齐!",atPosition:isBottom)
    }
    
//MARK: 添加App图标
    func pressAddButton(_ tapView:UIView?){
        self.hideTopbar = false
        self.setNeedsStatusBarAppearanceUpdate()
        let appendView = AppendVC()
        if let snapView = self.view.snapshot2View(){
            appendView.superSnapshotView = snapView
            if let sender = tapView{
                let rect = sender.superview!.convert(sender.frame, to: self.view)
                let position = CGPoint(x: rect.midX, y: rect.midY)
                appendView.superSnapshotPosition = position
            }else{
                appendView.superSnapshotPosition = CGPointZero
            }
        }
        appendView.modalPresentationStyle = .fullScreen
        self.present(appendView, animated: false)
    
        appendView.didAddAppBlock = { [weak self](appData) in
            self?.showNewAddApp(appData: appData)
        }
        appendView.didCloseBlock = { [weak self](snapshot) in
            self?.tapBackView()
            if let appendSnapshot = snapshot{
                let tmpView = UIImageView(frame: CGRect(x:0, y: 0, width: screen_W, height: screen_H))
                self?.view.addSubview(tmpView)
                tmpView.image = appendSnapshot
                tmpView.tag = 1023
            }
        }
    }
    func showNewAddApp(appData: String){
        let arr = appData.components(separatedBy: "&|&")
        if arr.count < 3 {
//显示error
            return
        }
        
//以urlscheme为唯一标识，添加前需选判断是否有urlscheme一样的存在，是则更新title和icon
//删除的时候不能以tag来删除
        
//简单点，新添加的，自动放在屏幕中间位置，由用户拖放其位置
        let topSpace = UIDevice.ui_navigationFullHeight()
        let bottomSpace = max(UIDevice.ui_safeDistanceBottom(), 15)
        let workHeight = screen_H-topSpace-bottomSpace
        let locate = CGPoint(x: screen_W/2 - appWidth/2, y: workHeight/2 - appHeight/2)
        
//alanizyAppItem先清空临时信息
        schemeSource.removeAll()
        titleSource.removeAll()
        icourlSource.removeAll()
        storeLinkSource.removeAll()
        var isNewApp = true
        if alanizyAppItem(arr: arr){ //最后一个即为新产生的图标
            let theScheme = schemeSource[0]
            if hasIcoLabelInCurrentPage(){
                for i in 0 ..< icoLabelList[iPageIndex].count{
                    let tmpScheme = icoLabelList[iPageIndex][i].appBid()
                    if tmpScheme == theScheme{
//存在则更新,图标及名称
                        let theTitle = titleSource[0]
                        let theIcourl = icourlSource[0]
                        let theStorelink = storeLinkSource[0]
                        icoLabelList[iPageIndex][i].setImage(imgName: theIcourl)
                        icoLabelList[iPageIndex][i].setTitle(title: theTitle)
                        icoLabelList[iPageIndex][i].setStoreLink(link: theStorelink)
                        let icoLabel = icoLabelList[iPageIndex][i]
                        doLongTapIcoLabel(icoLabel)
                        isNewApp = false
                        break
                    }
                }
            }
            
            if isNewApp{
                if let icoLabel = createAppIcoLabelAt(index: 0, point: locate,InPage: iPageIndex){
                    icoLabelList[iPageIndex].append(icoLabel)
                    doLongTapIcoLabel(icoLabel)
                }
            }
            
            isModified = true
           
        }
        
    }

    
    //MARK: - 选择壁纸
    func showWallPaperSelectDlg(_ pressButton:UIView? = nil){
        self.tapBackView()
        
        let wallPage = WallPaperVC()
        wallPage.modalPresentationStyle = .fullScreen
        
        if let sender = pressButton{
            if let snapView = self.view.snapshot2View(){
                wallPage.superSnapshotView = snapView
                let rect = sender.superview!.convert(sender.frame, to: self.view)
                let position = CGPoint(x: rect.midX, y: rect.midY)
                wallPage.superSnapshotPosition = position
            }
            self.present(wallPage, animated: false)
        }else{
            self.present(wallPage, animated: true)
        }
        
        wallPage.didCloseBlock = { [weak self] in
            if let appendSnapshot = wallPage.view.snapshot2Image(){ //因为循环引用了wallPage.view，故在wallPage中必须将didCloseBlock=nil才能deinit
                let tmpView = UIImageView(frame: CGRect(x:0, y: 0, width: screen_W, height: screen_H))
                self?.view.addSubview(tmpView)
                tmpView.image = appendSnapshot
                tmpView.tag = 1023
            }
        }
//回调壁纸papaerImage(主要非本地资源壁纸)
//回调壁纸路径(主要Gif图片处理，其保存的imageData不能用jpegData转，及本地资源图片，只需用存储imagename即可)
        wallPage.selectWallPaperForPage(self.iPageIndex) { [weak self](papaerImage,paperUrl) in
            if let self = self{
                if let image = papaerImage?.fixAlbumPhotoOrientation(){
                    //                self.pageWallList[self.iPageIndex].stopGifAnimating() //如果上一图像为Gif图片，须要先关闭动画，否则新设置图像无法显示
                    self.pageWallList[self.iPageIndex].image = image
                    let wallkey = String(format: "key_wallpaper_for_page_%d", self.iPageIndex)
                    if let imageUrl = paperUrl{
                        UserDefaults.standard.set(imageUrl, forKey: wallkey)
                    }else{
                        UserDefaults.standard.set(image.jpegData(compressionQuality: 0.2), forKey: wallkey)
                    }
                    UserDefaults.standard.synchronize()
                }else if let imageUrl = paperUrl{//Gif图片
                    self.pageWallList[self.iPageIndex].setImageWithStr(imgurl: imageUrl)
                    let wallkey = String(format: "key_wallpaper_for_page_%d", self.iPageIndex)
                    UserDefaults.standard.set(imageUrl, forKey: wallkey)
                    UserDefaults.standard.synchronize()
                }else{
                    self.view.showToast("壁纸为空，取消设置")
                }
                SDWebImageManager.shared.imageCache.clear?(with: .all)
            }
        }
    }
    
}


extension ViewController{
    //MARK: - 打开启动项
    func tapRunApp(sender:IcoLabel){
        let urlscheme = sender.appBid()
        let title = sender.title()
        let storeLink = sender.storeLink()
//url=xxx[&path=xx][&|&storelink=xx]&|&title=xx&|&icon=xxx
        let content = String(format: "url=%@%@&|&title=%@", urlscheme,storeLink.isEmpty ? storeLink : "&|&storelink="+storeLink,title)
        self.testRunWithCmd(content)
    }
    
    //MARK: - 删除图标
        func deleteApp(urlscheme:String){
            if hasIcoLabelInCurrentPage(){
                for i in 0 ..< icoLabelList[iPageIndex].count{
                    let tmpScheme = icoLabelList[iPageIndex][i].appBid()
                    if tmpScheme == urlscheme{
                        let icoLabel = icoLabelList[iPageIndex][i]
//                        let iSuperY = icoLabel.superview?.frame.origin.y
//                        let pos = CGPoint(x: icoLabel.center.x, y: iSuperY! + icoLabel.center.y)
//                        self.showPressCirlceHeart(2,pos)
                        Vibrations.warning.vibrate()
//方法一：
//                        let starsCrush = StarsViewGLAnimator()
//                        starsCrush.duration = 0.75
//                        starsCrush.xSmallDiff = -10.0
//                        starsCrush.xBigDiff = 10.0
//                        starsCrush.animateCrushView(crushView: icoLabel, In: icoLabel.superview!)
//方法二：
                        icoLabel.animateToCrush(crushSize: CGSize(width: 8, height: 10),xSmall: -5.0,xBig: 5.0, duration: 0.75)
                        if let _ = icoLabel.superview{
                            icoLabel.removeFromSuperview()
                        }
                        icoLabelList[iPageIndex].remove(at: i)
                        self.recordAppData()
                        if self.modingApp != nil{
//只有一个可编辑的情况下，删除，则结束UI编辑状态
                            self.tapBackView()
                        }
                        
                        
                        break
                    }
                }
            }
            
            
        }
        
    //MARK: - 编辑图标
        func modiApp(urlscheme:String){
            self.stopScreenSave()
            
            if hasIcoLabelInCurrentPage(){
                for i in 0 ..< icoLabelList[iPageIndex].count{
                    let tmpScheme = icoLabelList[iPageIndex][i].appBid()
                    if tmpScheme == urlscheme{
                        let title = icoLabelList[iPageIndex][i].title()
                        let icon = icoLabelList[iPageIndex][i].iconurl()
                        
                        let modiVC = ModiAppVC()
                        self.present(modiVC, animated: true)
                        modiVC.changeAppInfo(String(format: "%@&|&%@&|&%@", urlscheme,title,icon)) {[weak self](appData) in
                            if !appData.isEmpty{
                                let arr = appData.components(separatedBy: "&|&")
                                if let self = self,arr.count == 3{
                                    self.icoLabelList[self.iPageIndex][i].setAppBid(bid: arr[0])
                                    self.icoLabelList[self.iPageIndex][i].setTitle(title: arr[1])
                                    self.icoLabelList[self.iPageIndex][i].setImage(imgName: arr[2])
                                    self.recordAppData()
                                }
                            }
                        }
                        break
                    }
                }
            }
            
            
        }
        
    //MARK: - 移动图标
    func movingApp(sender:IcoLabel){
//        print("moveing:\(sender.frame.origin)")
        let pt = sender.frame.origin
        if pt.x<0 && iPageIndex>0{
            recordAppData() //先缓存当前要移开的页面数据
            UIView.animate(withDuration: 0.25, delay: 0.5) {
                self.scrollPageView.contentOffset = CGPoint(x: 0, y: 0)
            } completion: { finished in
                self.showCurrentPage(0)
            }
            
            
        }else if pt.x+sender.bounds.width>screen_W && 0 == iPageIndex{
            recordAppData()
            UIView.animate(withDuration: 0.25, delay: 0.25) {
                self.scrollPageView.contentOffset = CGPoint(x: screen_W, y: 0)
            } completion: { finished in
                self.showCurrentPage(1)
            }
        }
    }
    func moveAppBegin(sender:IcoLabel){
        isModified = true
        stopScreenSave()
        removeMovingBackView()
        
        let tmpList = icoLabelList[iPageIndex].filter { $0 != sender }
        print("\(icoLabelList[iPageIndex].count)--\(tmpList.count)")
        icoLabelList[iPageIndex] = tmpList
// sender.removeFromSuperview() //不能removeFromSuperview，再添加，否该图标的touch事件就会重置；而应该直接加到另一个View上，此时touch事件仍旧可以延续
        
        let topSpace = UIDevice.ui_navigationFullHeight()
        let bottomSpace = max(UIDevice.ui_safeDistanceBottom(), 15)
        let workHeight = screen_H-topSpace-bottomSpace

        let tmpView = UIView(frame: CGRect(x: 0, y: topSpace, width: screen_W, height: workHeight))
        self.view.addSubview(tmpView)
//        tmpView.backgroundColor = .cyan.withAlphaComponent(0.3)
        tmpView.addSubview(sender)
        tmpView.tag = 1520
        sender.forbidMoveToAnotherPage = false
    }
    
    func moveAppOver(sender:IcoLabel){
        isModified = true
//结束移动时也可立即保存
        sender.superview?.removeFromSuperview()
        pageWorkList[iPageIndex].addSubview(sender)
        sender.forbidMoveToAnotherPage = true
        
//进一步判断，如果出界了，则回缩
        var  lastframe = sender.frame
        let btnW = sender.frame.width
        let btnH = sender.frame.height
        var outflag = false //坐标是否越界
        if lastframe.minX<0 {
            outflag = true
            lastframe = CGRect(x: 0, y: lastframe.origin.y, width: btnW, height: btnH)
        }else if lastframe.maxX>screen_W{
            outflag = true
            lastframe = CGRect(x: screen_W-btnW, y: lastframe.origin.y, width: btnW, height: btnH)
        }
        let topSpace = UIDevice.ui_navigationFullHeight()
        let bottomSpace = max(UIDevice.ui_safeDistanceBottom(), 15)
        let workHeight = screen_H-topSpace-bottomSpace
        if lastframe.minY<0 {
            outflag = true
            lastframe = CGRect(x: lastframe.origin.x, y: 0, width: btnW, height: btnH)
        }else if lastframe.maxY>workHeight{
            outflag = true
            lastframe = CGRect(x: lastframe.origin.x, y: workHeight - btnH, width: btnW, height: btnH)
        }
        
        print("last:\(icoLabelList[iPageIndex].count)")
        icoLabelList[iPageIndex].append(sender)
        print("now:\(icoLabelList[iPageIndex].count)")
        
        removeMovingBackView()
        if outflag{
            UIView.animate(withDuration: 0.25, delay: 0.25) {
                sender.frame = lastframe
            } completion: { finished in
                self.recordAppData()
                self.exchangeAppLocation(sender: sender)
            }
        }else{
            recordAppData()
            exchangeAppLocation(sender: sender)
        }
    }
    
    func exchangeAppLocation(sender:IcoLabel){
//如果，在同一页内移动，且sender的中心点，位于其他某个App的区域内，则两者对调
        if sender.lastPage == iPageIndex{
            let theCenter = sender.center
            for perIco in icoLabelList[iPageIndex]{
                if perIco != sender{
                    if perIco.frame.contains(theCenter) && !perIco.frame.contains(sender.lastLocation){
                        print("\(perIco.title())--\(sender.title())")
                        let senderCenter = sender.lastLocation
                        let perIcoCenter = perIco.center
                        UIView.animate(withDuration: 0.75, delay: 0.25) {
                            perIco.center = senderCenter
                            sender.center = perIcoCenter
                        } completion: { finished in
                            self.recordAppData()
                        }
                        break
                    }
                }
            }
        }else{
            sender.lastPage = iPageIndex //切换到新页面
        }
    }
    
    func removeMovingBackView(){
        if let backView = self.view.viewWithTag(1520){
            backView.removeFromSuperview()
        }
    }
    
    //MARK: - 保存当前页面图标数据
    /*
       将当前页的每个App信息，按指定格式组合成字符串数组，然后保存
       每添加或修改或删除一个App，都须进行保存更新
     */
        func recordAppData(){
            let keyList = ["aiScreen.App.page1.data","aiScreen.App.page2.data","aiScreen.App.page3.data","aiScreen.App.page4.data","aiScreen.App.page5.data"]
            if !hasIcoLabelInCurrentPage(){
                UserDefaults.standard.removeObject(forKey: keyList[iPageIndex])
                UserDefaults.standard.removeObject(forKey: keyList[iPageIndex] + ".location")
                return
            }
            
            var arr:[String] = []
            var arrPoints:[String] = []
            for i in 0 ..< icoLabelList[iPageIndex].count{
                let schemeUrl = icoLabelList[iPageIndex][i].appBid()
                let title = icoLabelList[iPageIndex][i].title()
                let iconUrl = icoLabelList[iPageIndex][i].iconurl()
                let storeLink = icoLabelList[iPageIndex][i].storeLink()
//url=xxx[&path=xx][&|&storelink=xx]&|&title=xx&|&icon=xxx
                let strdata = String(format: "url=%@%@&|&title=%@&|&icon=%@", schemeUrl,storeLink.isEmpty ? "" : "&|&storelink="+storeLink,title,iconUrl)
                arr.append(strdata)
                //更新坐标
                let dx = icoLabelList[iPageIndex][i].frame.origin.x
                let dy = icoLabelList[iPageIndex][i].frame.origin.y
                let strPoints = String(format: "%0.2f&%0.2f", dx,dy)
                arrPoints.append(strPoints)
            }
            UserDefaults.standard.setValue(arr, forKey: keyList[iPageIndex])
            UserDefaults.standard.setValue(arrPoints, forKey: keyList[iPageIndex] + ".location") //CGPoint类型不能直接保存
        }

        
        func doLongTapIcoLabel(_ label:IcoLabel?){
            self.removeMovingBackView()
            self.stopScreenSave()
            
            self.scrollPageView.isScrollEnabled = false
            showToolButton(true)
            self.showMoveLine(true)
            self.modingApp = label
            if label != nil{
                self.stopAppShake(except: label)
                label!.superview?.bringSubviewToFront(label!)//将要移动的置前
            }
        }
        
        func shakeOtherApps(){
            if icoLabelList.count>iPageIndex{
                for perIcoLabel in self.icoLabelList[iPageIndex] {
                    perIcoLabel.startTapAnimate()
                }
            }
        }
        
        func stopAppShake(except nowLabel:IcoLabel?){
            if icoLabelList.count>iPageIndex{
                for perIcoLabel in self.icoLabelList[iPageIndex] {
                    if nowLabel == nil {
                        perIcoLabel.stopTapAnimate()
                    }else if perIcoLabel === nowLabel{
                        NSLog("is.same")
                    }else{
                        perIcoLabel.stopTapAnimate()
                    }
                }
            }
        }
}


//MARK: 全屏及底部条显隐
extension ViewController{
//控制顶部时间栏的显示与否
    override var prefersStatusBarHidden: Bool {
//prefersStatusBarHidden在viewDidLoad之后，viewDidAppear之前触发(此时不会生效)
//要使VC打开即生效，需在viewDidAppear里调用setNeedsStatusBarAppearanceUpdate刷新生效
        return hideTopbar  //设置屏幕是否全屏，true=全屏 ,ViewLoad后会触发此，但首次启动后并不会生效
    }
    
//控制iphonex底部横条的显示与否
    override var prefersHomeIndicatorAutoHidden: Bool{
//        self.setNeedsUpdateOfHomeIndicatorAutoHidden()刷新生效
        return hideBottomBar
    }
    
}

//MARK: - 显示隐私及协议
extension ViewController{
    func showProtoclOrNot(){
        let isAgreedProtocol = UserDefaults.standard.bool(forKey: "aiScreen.Agreed.Protocol")
        if !isAgreedProtocol{
            showProtocolDialog()
        }else{
            addMainViewTap()
            showScreenSaver()
            if !hasIcoLabelInCurrentPage(){
                self.tapBackView()
            }
        }
    }
    @objc func showProtocolDialog(){
        let dlgBackView = UIView(frame: CGRect(x: 0, y: 0, width: screen_W, height: screen_H))
        view.addSubview(dlgBackView)
        dlgBackView.backgroundColor = .black.withAlphaComponent(0.5)
        dlgBackView.layer.opacity = 0
        
        let workWidth = 290.0
        let workHeight = 340.0
        let dlgView = UIView(frame: CGRect(x: screen_W/2-workWidth/2, y: -workHeight, width: workWidth, height: workHeight))
        dlgBackView.addSubview(dlgView)
        dlgView.backgroundColor = .systemBackground
        dlgView.layer.cornerRadius = 15
        dlgView.clipsToBounds = true
        
        let titleLabel = UILabel(frame: CGRect(x: 0, y: 5, width: workWidth, height: 30))
        dlgView.addSubview(titleLabel)
        titleLabel.text = "欢迎您使用 aiScreen(我的Ai桌面)"
        titleLabel.font = .boldSystemFont(ofSize: 15)
        titleLabel.textColor = .label
        titleLabel.textAlignment = .center
        
        let subTitle = UILabel(frame: CGRect(x: 0, y: 35, width: workWidth, height: 15))
        dlgView.addSubview(subTitle)
        subTitle.text = "浙ICP备2021025253号-4A"
        subTitle.font = .systemFont(ofSize: 13)
        subTitle.textColor = .secondaryLabel
        subTitle.textAlignment = .center
        
        let customType1 = ActiveType.custom(pattern: "\\《aiScreen用户协议\\》")
        let customType2 = ActiveType.custom(pattern: "\\《aiScreen隐私政策\\》")
        let label = ActiveLabel()
        label.enabledTypes.append(customType1)
        label.enabledTypes.append(customType2)
        label.customize { [weak self] (label) in
            label.text =  "aiScreen(我的Ai桌面)非常注重您的隐私保护和个人信息保护，在您使用aiScreen前，请您认真阅读并理解《aiScreen用户协议》和《aiScreen隐私政策》。如已了解我们的协议规范，请点击“同意并继续”以便我们能为继续您服务！\n感谢您的理解与支持 -_-"
            label.numberOfLines = 0
            label.lineSpacing = 4
            label.textColor = .label.withAlphaComponent(0.75)
            label.font = .systemFont(ofSize: 14)
            
            label.customColor[customType1] = .link
            label.customSelectedColor[customType1] = UIColor.green
            label.customColor[customType2] = .link
            label.customSelectedColor[customType2] = UIColor.green
//label.handleCustomTap与self.view的tapGusture有冲突
            label.handleCustomTap(for: customType1) { _ in
//                playVibrate(iVibrate: 2)
                Vibrations.selection.vibrate()
                let webVC = WebViewController()
                self?.present(webVC, animated: true)
                webVC.loadUrlStr(urlstr: "http://apk.hhkyj.com/terms.html",title: "aiScreen-用户协议")
            }
            label.handleCustomTap(for: customType2) { _ in
//                playVibrate(iVibrate: 2)
                Vibrations.selection.vibrate()
                let webVC = WebViewController()
                self?.present(webVC, animated: true)
                webVC.loadUrlStr(urlstr: "http://apk.hhkyj.com/privacy.html",title: "aiScreen-隐私协议")
            }
        }
        label.frame = CGRect(x: 20, y: 50, width: workWidth-40, height: 190)
        dlgView.addSubview(label)
        
        let cancelBtn = UIButton(frame: CGRect(x: workWidth/2 - 80/2, y: workHeight - 20 - 16, width: 80, height: 16))
        dlgView.addSubview(cancelBtn)
        cancelBtn.setTitle("不同意", for: .normal)
        cancelBtn.setTitleColor(.secondaryLabel, for: .normal)
        cancelBtn.titleLabel?.font = .systemFont(ofSize: 13)
        cancelBtn.addActionWithBlock {sender in
//显示提示，必须同意才能继续使用
//            playVibrate(iVibrate: 3)
            Vibrations.error.vibrate()
            dlgBackView.showToast("经得您同意，我们才能继续为您服务！",atPosition: false)
        }
        
        let OKBtn = UIButton(frame: CGRect(x: 20, y: cancelBtn.frame.minY - 15 - 40, width: workWidth-40, height: 40))
        dlgView.addSubview(OKBtn)
        OKBtn.layer.cornerRadius = 20
        OKBtn.setTitle("同意并继续", for: .normal)
        OKBtn.setTitleColor(.white, for: .normal)
        OKBtn.titleLabel?.font = .boldSystemFont(ofSize: 16)
        OKBtn.backgroundColor = prjTitleColor
        OKBtn.addActionWithBlock { [weak self] (sender) in
//            playVibrate(iVibrate: 1)
            Vibrations.success.vibrate()
            for perView in dlgBackView.subviews{
                perView.removeFromSuperview()
            }
            dlgBackView.removeFromSuperview()
            UserDefaults.standard.set(true, forKey: "aiScreen.Agreed.Protocol")
            UserDefaults.standard.synchronize()
            
            self?.loadDefaultApp()
            self?.addMainViewTap()
        }
        
        UIView.animate(withDuration: 0.25, delay: 0.75,options: [.curveEaseInOut]) {
            dlgBackView.layer.opacity = 1.0
        } completion: { isfinished in
            UIView.animate(withDuration: 0.5, delay: 0.25, usingSpringWithDamping: 0.5, initialSpringVelocity: 25,options: [.curveEaseInOut]) {
                dlgView.frame = CGRect(x: screen_W/2-workWidth/2, y: screen_H/2-workHeight/2, width: workWidth, height: workHeight)
            }
        }
    }
    
    func addMainViewTap(){
        let tapView = UITapGestureRecognizer(target: self, action: #selector(handlePress))
//tapView.cancelsTouchesInView = false //默认为true,为true时可能会与view上的其他tap有冲突导致其他tap要2指点击才会触发,如与协议对话框中的点击冲突
        //如果cancelsTouchesInView设置成false,则在点view上的App删除、编辑等按钮时，也会触发tapBackView
//        tapView.delaysTouchesBegan = false
//        tapView.delaysTouchesEnded = false
        self.view.addGestureRecognizer(tapView)
    }
    func removeMainViewTap(){
        let tapView = UITapGestureRecognizer(target: self, action: #selector(handlePress))
        self.view.removeGestureRecognizer(tapView)
    }
}

//MARK: - noti
extension ViewController{
    func initNoti(){
        NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
//        NotificationCenter.default.addObserver(self, selector: #selector(applicationWillResignActive), name: UIApplication.willResignActiveNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(applicationEnterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(terminateApp), name: UIApplication.willTerminateNotification, object: nil)

//    电量及充电状态监控
        UIDevice.current.isBatteryMonitoringEnabled = true //请确保已启用电池监视
        NotificationCenter.default.addObserver(self, selector: #selector(batteryLevelDidChange), name: UIDevice.batteryLevelDidChangeNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(batteryStateDidChange), name: UIDevice.batteryStateDidChangeNotification, object: nil)
    }
//首次启动(在viewDidAppear前触发) or 后台切换到前台
    @objc func applicationDidBecomeActive(notification: NSNotification) {
        if(self.isViewLoaded){
            if (self.modingApp != nil && !self.topbarView.isHidden){ //从其它页面回来，动画会停掉
                self.stopAppShake(except: self.modingApp!)
                self.modingApp?.enabelEdit()
            }
            showBatteryOrNot()
            showScreenSaver()
            print("applicationDidBecomeActive")
        }
    }
    
    @objc func applicationEnterBackground(notification: NSNotification) {
        self.removeBatteryAnimate()
        self.stopScreenSave()
        print("applicationEnterBackground")
    }
    
    @objc func batteryLevelDidChange(_ notification: Notification) {
//电池电量从0.0（完全放电）到1.0（100％充电）
        showBatteryOrNot()
        initLeftBar()
    }

    @objc func batteryStateDidChange(_ notification: Notification) {
//电池状态.unknown(模拟器)/.unplugge未充电/.charging充电中/.full满电
        showBatteryOrNot()
        showScreenSaver()
    }
    
    @objc func terminateApp(){
        print("terminateApp.now")
    }
    
}

//MARK: - battery
extension ViewController{
    func showBatteryOrNot(){
        //充电状态及电量事件件不是每次都触发的(电量改变,或插拨时才会触发)，故在显示时手动调用:
        if let _ = self.view.viewWithTag(1198){
//在屏保状态
            removeBatteryAnimate()
        }else{
            if (batteryState == .charging) || (batteryState == .full)  {
                let ilast = UserDefaults.standard.value(forKey: "aiScreen.battery.animation.i") as? Int
                showBatteryAnimation(ilast)
            }else{
                removeBatteryAnimate()
            }
        }
    }
    
    func removeBatteryAnimate(){
//关停进度条动画
        stopBatteryTimer()
//关停烟花,火箭,冒泡等动画
        if batteryEmitter != nil{
            batteryEmitter?.removeFromSuperlayer()
            batteryEmitter = nil
        }
//关停波浪
        if batteryWave != nil{
            batteryWave?.endWave()
            for perView in batteryWave!.subviews{
                perView.removeFromSuperview()
            }
            batteryWave?.removeFromSuperview()
            batteryWave = nil
        }
        
        if batteryView != nil{
            for perView in batteryView!.subviews{
                perView.removeFromSuperview()
            }
            batteryView?.removeFromSuperview()
            batteryView = nil
        }
        
    }
    
    func showBatteryProgress(){
        let batteryBackView = pageWallList[iPageIndex].viewWithTag(1990+iPageIndex)
        
        if batteryView != nil && batteryView?.superview != batteryBackView{
            removeBatteryAnimate()
        }
        
        if batteryView == nil{
            let backView = UIImageView(image: UIImage(named: "battery_bg@2x.png"))
            if batteryBackView != nil{
                batteryBackView!.addSubview(backView)
            }else{
                self.view.addSubview(backView)
            }
            backView.frame = CGRect(x: screen_W/2-110/2, y: screen_H+5, width: 110, height: 24) //110*24
            let batteryProgress = UIView(frame: CGRect(x: 12, y: 6, width: 0, height: 12)) //58*12
            backView.addSubview(batteryProgress)
            batteryProgress.backgroundColor = UIColor("0cd747") //绿色电量进度
            batteryProgress.layer.cornerRadius = 2 //电量进度条
            batteryProgress.tag = 101
            
            let progressImg = UIImageView(image: UIImage(named: "battery_probar@2x.png")) //116*24(2x)
            backView.addSubview(progressImg)
            progressImg.frame = CGRect(x: 12, y: 6, width: 58, height: 12)
            progressImg.layer.borderWidth = 0.5
            progressImg.layer.borderColor = UIColor("3f3f3f").cgColor
            progressImg.layer.cornerRadius = 2 //电量进度条背景
            
            let batteryTips = UILabel(frame: CGRect(x: 15+55+3, y: 6, width: 110-12-55-10, height: 12))
            backView.addSubview(batteryTips)
            batteryTips.text = "0"
            batteryTips.textColor = .white
            batteryTips.font = UIFont.systemFont(ofSize: 11)
            batteryTips.tag = 102
            batteryView = backView
            
            UIView.animate(withDuration: 0.45, delay: 0.25,options: [.curveEaseInOut]) {
                backView.frame = CGRect(x: screen_W/2-110/2, y: screen_H-20, width: 110, height: 24)
            }
        }
        
        if let batteryTips = batteryView?.viewWithTag(102) as? UILabel{
            if batteryLevel <= 0 {
                batteryTips.text = "0"
            }else{
                batteryTips.text = String(format: "\(Int(batteryLevel*100))%%")
            }
        }
        if let batteryProgress =  batteryView?.viewWithTag(101){
            if batteryLevel>=0{
                batteryProgress.frame = CGRect(x: 12.0, y: 6.0, width: Double(batteryLevel) * 58, height: 12.0) //100%时width=58
            }else{
                batteryProgress.frame = CGRect(x: 12.0, y: 6.0, width: 1.0, height: 12.0) //不可能有的情况
            }
        }
        if batteryLevel < 1{
//电量未满，则动画
            beginBatteryAnimate()
        }else{
//停止动画
            stopBatteryTimer()
        }
    }
    
    
    
    func beginBatteryAnimate(){
        func updateBatteryAnimate(_ batteryProgress:UIView){
                UIView.animate(withDuration: 0.75, delay: 0, options: [.curveEaseInOut]) {[weak self] in
                    if batteryProgress.frame.width < 58 {
                        batteryProgress.frame = CGRect(x: 12.0, y: 6.0, width: 58, height: 12.0)
                    }else if let self = self{
                        var level = self.batteryLevel
                        if level>0.9 && level<1.0{
                            level = 0.9 //以便动画能看出来
                        }
                        if level>0{
                            batteryProgress.frame = CGRect(x: 12.0, y: 6.0, width: Double(level) * 58, height: 12.0) //100%时width=58
                        }else{
                            batteryProgress.frame = CGRect(x: 12.0, y: 6.0, width: 1.0, height: 12.0) //不可能有的情况
                        }
                    }
                }
            
        }
        
        if batteryTimer == nil{
            batteryTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { [weak self](timer) in
                if let batteryProgress =  self?.batteryView?.viewWithTag(101){
                    updateBatteryAnimate(batteryProgress)
                }
            })
//           Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateBatteryAnimate), userInfo: nil, repeats: true)
            if let curTimer: Timer = batteryTimer {
                RunLoop.main.add(curTimer, forMode: .common)//UI滑动等导致timer计时不准确的情况，设置timer的mode为NSRunLoopCommonModes
                curTimer.fire() //马上触发，不然显示会慢1秒
            }
        }
    }
    
    func stopBatteryTimer(){
        if batteryTimer != nil{
            batteryTimer?.invalidate()
            batteryTimer = nil
        }
    }

    func showBatteryFireworksAnimate(){
//烟花
        removeBatteryAnimate()
        let batteryBackView = pageWallList[iPageIndex].viewWithTag(1990+iPageIndex)
        let backView = UIImageView(frame: CGRect(x: 0, y: 0, width: screen_W, height: screen_H))
        if batteryBackView != nil{
            batteryBackView?.addSubview(backView)
        }else{
            self.view.addSubview(backView)
        }
        batteryView = backView
        
        let fireworkdEmitter = CAEmitterLayer()
        let viewBounds = backView.layer.bounds
        fireworkdEmitter.emitterPosition = CGPointMake(viewBounds.size.width/2, viewBounds.size.height)
        fireworkdEmitter.emitterMode = .outline
        fireworkdEmitter.emitterShape = .line
        fireworkdEmitter.renderMode = .additive
//        fireworkdEmitter.emitterSize = CGSize(width: viewBounds.size.width, height: 1)
//        这样则是在底部任一点上向上发射，没有此句则从emitterPosition底部中间点发射
        fireworkdEmitter.emitterSize = CGSize(width: 50, height: 1) //x-50,x+50
        
        fireworkdEmitter.seed = (arc4random()%100)+1 //指定用于初始化随机数生成器的种子

        //创建火箭cell
        let rocket = CAEmitterCell()
        rocket.birthRate = 10
        rocket.emissionRange = 0.15 * Double.pi
        rocket.velocity = 600
        rocket.velocityRange = 180
        rocket.lifetime = 1.02
//        粒子生命周期系数，默认为1.0。如果设置为0，那么发射源停止发射粒子，粒子的声明周期为0，屏幕不在渲染了。
        rocket.contents = #imageLiteral(resourceName: "bat_emt_sparkRocket.png").cgImage
        rocket.scale = 0.5
        rocket.scaleRange = 0.4
//        rocket.scaleSpeed = -0.1
        rocket.color = #colorLiteral(red: 0.8549019694, green: 0.250980407, blue: 0.4784313738, alpha: 1)
        rocket.greenRange = 1.0 //粒子的绿色成分可以变化的数量
        rocket.redRange = 1.0
        rocket.blueRange = 1.0
        rocket.spinRange = Double.pi //粒子cell在其生命周期内的自旋变化量
//
//        //破裂对象不能被看到,但会产生火花
//        //这里我们改变颜色,因为火花继承它的值
        let fireCell = CAEmitterCell()
        fireCell.birthRate = 1
        fireCell.velocity = 0
        fireCell.scale = 1
        fireCell.redSpeed = fireCell.redSpeed - 1.5 //红色成分在粒子生命周期内的变化速度
        fireCell.blueSpeed = fireCell.blueSpeed + 1.5
        fireCell.greenSpeed = fireCell.greenSpeed + 1.5;        // shifting
        fireCell.lifetime = 0.34

//        // and finally, the sparks
        let spark = CAEmitterCell()
        spark.birthRate = 400       //炸开后产生400个小烟花
        spark.velocity             = 225       //速度
        spark.emissionRange        = 2 * Double.pi   // 360 度
        spark.yAcceleration        = 100         // 重力 y轴方向的加速度,default = 0
        spark.lifetime             = 2.5

        spark.contents          =  #imageLiteral(resourceName: "bat_emt_spark.png").cgImage
        
        spark.scale = 0.5
        spark.scaleRange = 0.3
        spark.scaleSpeed        = spark.scaleSpeed - 0.15 //粒子cell的生命周期内，scale每秒的变化速率，默认值0.0

        spark.greenSpeed        = spark.greenSpeed - 0.2
        spark.redSpeed          = spark.redSpeed + 0.3
        spark.blueSpeed         = spark.blueSpeed - 0.5

        spark.alphaSpeed        = spark.alphaSpeed - 0.25
//
        spark.spin              = 2 * Double.pi
        spark.spinRange         = 2 * Double.pi
//
        fireworkdEmitter.emitterCells  = [rocket] //添加烟花升空粒子
        rocket.emitterCells = [fireCell] //每个粒子cell 又能添加 cell， 让粒子变颜色
        fireCell.emitterCells = [spark]
        
        batteryView?.layer.addSublayer(fireworkdEmitter)
        
        batteryEmitter = fireworkdEmitter
    }
    
    func showwBatteryRocketAnimate(){
//步步高
        removeBatteryAnimate()
        let batteryBackView = pageWallList[iPageIndex].viewWithTag(1990+iPageIndex)
        let backView = UIImageView(frame: CGRect(x: 0, y: 0, width: screen_W, height: screen_H))
        if batteryBackView != nil{
            batteryBackView?.addSubview(backView)
        }else{
            self.view.addSubview(backView)
        }
        batteryView = backView
        
        let fireworkdEmitter = CAEmitterLayer()
        let viewBounds = backView.layer.bounds
        fireworkdEmitter.emitterPosition = CGPointMake(viewBounds.size.width/2, viewBounds.size.height)
        fireworkdEmitter.emitterMode = .outline
        fireworkdEmitter.emitterShape = .line
        fireworkdEmitter.renderMode = .additive
//        fireworkdEmitter.emitterSize = CGSize(width: viewBounds.size.width, height: 1)
//        这样则是在底部任一点上向上发射，没有此句则从emitterPosition底部中间点发射
        fireworkdEmitter.emitterSize = CGSize(width: 50, height: 1) //x-50,x+50
        
        fireworkdEmitter.seed = (arc4random()%100)+1 //指定用于初始化随机数生成器的种子

        //创建火箭cell
        let rocket = CAEmitterCell()
        rocket.birthRate = 5
//        rocket.emissionRange = 0.15 * Double.pi
        rocket.velocity = 100
        rocket.velocityRange = 50
        rocket.lifetime = 1.0

        rocket.contents = #imageLiteral(resourceName: "bat_emt_bbgRocket.png").cgImage
        rocket.scale = 0.5
        rocket.scaleRange = 0.4
//        rocket.scaleSpeed = -0.1
        rocket.color = #colorLiteral(red: 0.9529411793, green: 0.6862745285, blue: 0.1333333403, alpha: 1)
        rocket.greenRange = 1.0 //粒子的绿色成分可以变化的数量
        rocket.redRange = 1.0
        rocket.blueRange = 1.0
        rocket.greenSpeed = -0.2
        rocket.redSpeed = 1.5
//        rocket.spinRange = Double.pi //粒子cell在其生命周期内的自旋变化量
        
        let spark = CAEmitterCell()
        spark.birthRate = 400       //炸开后产生400个小烟花
        spark.velocity             = 100       //速度
        spark.emissionRange        = 2 * Double.pi   // 360 度
        spark.yAcceleration        = 80         // 重力 y轴方向的加速度,default = 0
        spark.lifetime             = 5

        spark.contents          =  #imageLiteral(resourceName: "bat_emt_bbgSpark.png").cgImage
        
        spark.scale = 0.5
        spark.scaleRange = 0.3
        spark.scaleSpeed        = spark.scaleSpeed - 0.15 //粒子cell的生命周期内，scale每秒的变化速率，默认值0.0

        spark.greenSpeed        = spark.greenSpeed - 0.2
        spark.redSpeed          = spark.redSpeed + 0.1
        spark.blueSpeed         = spark.blueSpeed - 0.5

        spark.alphaSpeed        = spark.alphaSpeed - 0.25
//
        spark.spin              = 2 * Double.pi
        spark.spinRange         = 2 * Double.pi
//
        fireworkdEmitter.emitterCells  = [rocket] //添加烟花升空粒子
        rocket.emitterCells = [spark]
        
        batteryView?.layer.addSublayer(fireworkdEmitter)
        
        batteryEmitter = fireworkdEmitter
    }
    
    func showwBatteryGoldOutAnimate(){
//地涌金莲
        func emitterCell(withImage image: UIImage, usingColor color: UIColor? = nil) -> CAEmitterCell {
            
            let emitterCell = CAEmitterCell()
    //粒子cell
            emitterCell.birthRate  = 15
    //每秒产生粒子对象的数量
            
            emitterCell.lifetime = 5
    //粒子cell的生命周期，以秒计算。
    //假如，Cell的lifetime（生命周期）为1，其所属CAEmitterLayer的lifetime为2时，
    //在其它参数选择默认值的情况下，这个CAEmitterCell的生命周期就是1*2=2秒，2秒后，CAEmitterCell就会从粒子系统中被移除。
            emitterCell.lifetimeRange = 3
    // 粒子cell的生命周期变化范围。比如lifetime为10秒，lifttimeRange是3秒，那么cell的实际生命周期范围是7(10-3)到13(10+3)秒。
            
            emitterCell.velocity = 200 // the bigger the value is, the quicker the fruit move
    //粒子cell的初始速度 （cell.velocity 乘以 layer.velocity）等于粒子的速度
            emitterCell.velocityRange = 50
    //粒子cell的速度变化范围 velocity-velocityRange to velocity+velocityRange
            
            emitterCell.emissionLongitude = 0
    //发射角的经度方向。经度角代表了在x-y轴平面坐标系中与x轴之间的夹角，也就是粒子在xy平面的发射角度，默认0，切记在iOS上0度角表示Y轴向上的方向，（并不是x轴向右飞行。）
    //顺时针方向是正向，所以如果想沿着y轴向下飞行，那么在iOS中需设置为PI即即180度，如果粒子沿着x轴向左飞行，则可设置为 3*PI/2也可设置为 -PI/2。
    //而emissionLatitude指定了纬度, 纬度角代表了x-z轴平面上与x轴之间的夹角，两者默认0:
            
            emitterCell.emissionRange     = Double.pi/2
    //发射粒子角度范围，默认0，以锥形分布开的发射角度。角度用弧度制。粒子均匀分布在这个锥形范围内。
    //比如emissionLongitude=M_PI，则发射角度Y轴笔直向下，再叠加emissionRange=M_2_PI，则会向Y轴偏左下4度和Y轴偏右4度范围内发射
            emitterCell.contents          = image.cgImage
    //显示内容
            
            emitterCell.scale = 0.5
    //粒子缩放比例系数，默认为1.0
            emitterCell.scaleRange = 0.3
    //单元大小改变的范围，即实际的放缩为scale-scaleRange~scale+scaleRange不等
    //这个range 和 speed 决定了在单元存活时间里，它的大小变化的范围和速度
            emitterCell.scaleSpeed  = 0.2 // The bigger the value is, the quicker the fruit size grow
    //粒子cell的生命周期内，scale每秒的变化速率，默认值0.0; 为正数表示粒子由小大到变化，为负数表示粒子由大到小变化
    //        emitterCell.alphaSpeed = -1
    //        alpha成分在细胞生命周期内的变化速度(以秒为单位),为负数表从不透明到透明
            if let color = color {
                emitterCell.color = color.cgColor//粒子的颜色，默认为不透明的白色。
            }
            emitterCell.spin = Double.pi
            emitterCell.spinRange = 2 * Double.pi
            emitterCell.yAcceleration = 180         // 重力 y轴方向的加速度,default = 0
            return emitterCell
        }
        
        removeBatteryAnimate()
        let batteryBackView = pageWallList[iPageIndex].viewWithTag(1990+iPageIndex)
        let backView = UIImageView(frame: CGRect(x: 0, y: 0, width: screen_W, height: screen_H))
        if batteryBackView != nil{
            batteryBackView?.addSubview(backView)
        }else{
            self.view.addSubview(backView)
        }
        batteryView = backView
        
        let emitter = CAEmitterLayer()
//CAEmitterLayer用于实现基于Core Animation的粒子发生器系统。
        emitter.emitterShape    = .line
        let viewBounds = backView.layer.bounds
        emitter.emitterPosition = CGPointMake(viewBounds.size.width/2, viewBounds.size.height)
        emitter.emitterSize     = CGSize(width: 50, height: 1)
        emitter.renderMode      = .unordered
        let emotionsIcons = [#imageLiteral(resourceName: "bat_emt_money1.png"), #imageLiteral(resourceName: "bat_emt_money2.png"), #imageLiteral(resourceName: "bat_emt_money3.png"),#imageLiteral(resourceName: "bat_emt_money4.png"), #imageLiteral(resourceName: "bat_emt_money5.png"), #imageLiteral(resourceName: "bat_emt_money6.png")]
        emitter.emitterCells  = emotionsIcons.map { emitterCell(withImage: $0) }
 
        batteryView?.layer.addSublayer(emitter)
        batteryEmitter = emitter
    }
    
    func showwBatteryWaveAnimate(){
//波浪特效
        removeBatteryAnimate()
        // 创建波浪视图
        let bottomSpace = max(UIDevice.ui_safeDistanceBottom(), 15) //iphone8下为0
        let maxHeight = appHeight + bottomSpace
        var waveHeight = Double(batteryLevel) * maxHeight
        if waveHeight < 15{
            waveHeight = 15.0
        }
        
        let waveView = WaveView(frame: CGRect(x: 0, y: screen_H+1, width: screen_W+3,height: waveHeight))
        waveView.waveOnBottom = false
        let calender = Calendar(identifier: .gregorian)
        let comps = calender.dateComponents([.hour], from: Date())
        if let hour = comps.hour{
            if hour>5 && hour < 18{
                waveView.realWaveColor = UIColor("2c8fb7").withAlphaComponent(0.45)
                waveView.maskWaveColor = UIColor("2c8fb7").withAlphaComponent(0.25)
            }else{
                waveView.realWaveColor = UIColor("2e4651").withAlphaComponent(0.45)
                waveView.maskWaveColor = UIColor("2e4651").withAlphaComponent(0.25)
            }
        }else{
            waveView.realWaveColor = .cyan.withAlphaComponent(0.25)
            waveView.maskWaveColor = .cyan.withAlphaComponent(0.15)
        }
        
        let batteryBackView = pageWallList[iPageIndex].viewWithTag(1990+iPageIndex)
        if batteryBackView != nil{
            batteryBackView?.addSubview(waveView)
        }else{
            self.view.addSubview(waveView)
        }
        
        let batteryLabel = UILabel(frame: CGRect(x: screen_W/2-100, y: waveHeight/2 - 12/2, width: 200, height: 12))
        batteryLabel.font = .systemFont(ofSize: 10)
        batteryLabel.textColor = .white
        batteryLabel.textAlignment = .center
        if batteryLevel <= 0 {
            batteryLabel.text = "充电中..."
        }else{
            batteryLabel.text = String(format: "充电中(\(Int(batteryLevel*100))%%)")
        }
        waveView.addSubview(batteryLabel)
        batteryLabel.isHidden = true
        // 波浪动画回调
        waveView.closure = {centerY in
            // 同步更新文本标签的y坐标
            batteryLabel.frame.origin.y = waveHeight-12-centerY
        }
//       waveView.startWave()// 开始播放波浪动画
        self.batteryWave = waveView
        waveView.wave()
    
        UIView.animate(withDuration: 1.25, delay: 0.25,options: [.curveEaseInOut]) {
            waveView.frame = CGRect(x: 0, y: screen_H - waveHeight, width: screen_W,height: waveHeight)
        } completion: { finished in
            if finished{
                waveView.startWave()// 开始播放波浪动画
                batteryLabel.isHidden = false
            }
        }
    }
    
    func showwBatteryPaopaoAnimate(){
//冒泡特效
        func emitterCell(withImage image: UIImage, usingColor color: UIColor? = nil) -> CAEmitterCell {
            let emitterCell = CAEmitterCell()
    //粒子cell
            emitterCell.birthRate  = 1
    //每秒产生粒子对象的数量
            
            emitterCell.lifetime = 10
            emitterCell.lifetimeRange = 3
    // 粒子cell的生命周期变化范围。比如lifetime为10秒，lifttimeRange是3秒，那么cell的实际生命周期范围是7(10-3)到13(10+3)秒。
            
            emitterCell.velocity = 100 // the bigger the value is, the quicker the fruit move
    //粒子cell的初始速度 （cell.velocity 乘以 layer.velocity）等于粒子的速度
            emitterCell.velocityRange = 20
    //粒子cell的速度变化范围 velocity-velocityRange to velocity+velocityRange
            
            emitterCell.emissionLongitude = 0
            
            emitterCell.emissionRange     = Double.pi/4
    //发射粒子角度范围，默认0，以锥形分布开的发射角度。角度用弧度制。粒子均匀分布在这个锥形范围内。
    //比如emissionLongitude=M_PI，则发射角度Y轴笔直向下，再叠加emissionRange=M_2_PI，则会向Y轴偏左下4度和Y轴偏右4度范围内发射
            emitterCell.contents = image.cgImage
    //显示内容
            
            emitterCell.scale = 0.5
    //粒子缩放比例系数，默认为1.0
            emitterCell.scaleRange = 0.3
    //单元大小改变的范围，即实际的放缩为scale-scaleRange~scale+scaleRange不等
    //这个range 和 speed 决定了在单元存活时间里，它的大小变化的范围和速度
            emitterCell.scaleSpeed  = 0.1 // The bigger the value is, the quicker the fruit size grow
    //粒子cell的生命周期内，scale每秒的变化速率，默认值0.0; 为正数表示粒子由小大到变化，为负数表示粒子由大到小变化
//            emitterCell.alphaSpeed = -0.1
    //        alpha成分在细胞生命周期内的变化速度(以秒为单位),为负数表从不透明到透明
            emitterCell.spin = 1/Double.pi
            emitterCell.spinRange =  Double.pi
//            emitterCell.yAcceleration = 5
            emitterCell.greenRange = 1.0 //粒子的绿色成分可以变化的数量
            emitterCell.redRange = 1.0
            emitterCell.blueRange = 1.0
            emitterCell.greenSpeed = -0.01
            emitterCell.redSpeed = -0.01
            emitterCell.blueSpeed = -0.01
            
            return emitterCell
        }
        
        removeBatteryAnimate()
        let batteryBackView = pageWallList[iPageIndex].viewWithTag(1990+iPageIndex)
        let backView = UIImageView(frame: CGRect(x: 0, y: 0, width: screen_W, height: screen_H))
        if batteryBackView != nil{
            batteryBackView?.addSubview(backView)
        }else{
            self.view.addSubview(backView)
        }
        batteryView = backView
        
        let emitter = CAEmitterLayer()
//CAEmitterLayer用于实现基于Core Animation的粒子发生器系统。
        emitter.emitterShape    = .line
//        emitter.emitterMode = .outline
        let viewBounds = backView.layer.bounds
        emitter.emitterPosition = CGPointMake(viewBounds.size.width/2, viewBounds.size.height)
        emitter.emitterSize     = CGSize(width: 100, height: 1)
        emitter.renderMode      = .unordered
        emitter.seed = (arc4random()%100)+1
        
        let emotionsIcons = [#imageLiteral(resourceName: "bat_emt_paopao1.png"), #imageLiteral(resourceName: "bat_emt_paopao2.png"),  #imageLiteral(resourceName: "bat_emt_paopao3.png")]
        
        emitter.emitterCells  = emotionsIcons.map { emitterCell(withImage: $0) }
 
        batteryView?.layer.addSublayer(emitter)
        batteryEmitter = emitter
    }
    
    
}

extension ViewController{
//MARK: - 显示屏保
    func stopScreenSave(){
        if let saverView = self.view.viewWithTag(1198){
            for perView in saverView.subviews{
                perView.removeFromSuperview()
            }
            saverView.removeFromSuperview()
        }
        NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(doShowSaver), object: nil)
        self.hideTopbar = false
        self.setNeedsStatusBarAppearanceUpdate()
    }
    
    func showScreenSaver(){
        stopScreenSave()
        if (!isShowed){
            return
        }
        if self.topbarView.isHidden{
            var idleTime = 5.0
            if let ilast = UserDefaults.standard.value(forKey: "aiScreen.saver.iflag") as? Int{
                switch ilast{
                case 1:
                    idleTime = 10.0
                case 2:
                    idleTime = 15.0
                case 3:
                    idleTime = 30.0
                case 4:
                    idleTime = 60.0
                case 5:
                    idleTime = 0
                default: //or 0
                    idleTime = 5.0
                }
            }
            if idleTime>0{//0不显示屏保
                self.perform(#selector(doShowSaver), with: nil, afterDelay: idleTime) //ns之内无操作显示屏保
            }
        }
    }
    
    func getSaverUrl()->String?{
//动态壁纸(屏保有3种)网络http、相册类动态壁纸：file://xxx.gif、aiScreen.pCache.album.gif
        func isRightAblumFile(_ filePath:String)->Bool{
            if filePath == albumGifDataKey{
                if let _ = UserDefaults.standard.data(forKey: filePath){
                    return true
                }
            }else{
                let lowPath = filePath.lowercased()
                if lowPath.hasPrefix("file://") && lowPath.hasSuffix(".gif"){
                    if let imgUrl = URL(string: filePath){
                        if let _ = NSData(contentsOf: imgUrl){
                            return true
                        }
                    }
                }
            }
            return false
        }
        
        func getBatteryUrl()->String?{
            let batUrl = UserDefaults.standard.string(forKey: "aiScreen.saver.batteryUrl")
            if batUrl != nil{
// file:///private/var/mobile/Containers/Data/Application/F300240A-05D1-46D4-9F0D-43E3FF9A90DA/tmp/89D4142A-9EA7-4719-94D8-D2619359189A.gif
//如果是相册Gif，则进一步判断该图片是否能加载成功
                if batUrl!.lowercased().hasPrefix("http"){
                    return batUrl
                }
                else if isRightAblumFile(batUrl!){
                    return batUrl
                }
            }
            return nil
        }
        
        var idefault = 1//默认自定义屏保
        if let ilast = UserDefaults.standard.value(forKey: "aiScreen.saverMore.iflag") as? Int{
            idefault = ilast
        }
        if idefault>=2{
            return "\(idefault)"
        }
        
//0、充电时优先充电屏保
        if (batteryState == .charging) || (batteryState == .full){
            if let batUrl = getBatteryUrl(){
                return batUrl
            }
        }
//1、优先读取设置，没有则读取当前动态壁纸
        let url = UserDefaults.standard.string(forKey: "aiScreen.saver.picurl")
        if url != nil {//其次空闲屏保
            if url!.lowercased().hasPrefix("http"){
                return url
            }else if isRightAblumFile(url!){
                return url
            }
        }
        
//2、其次动态壁纸
        let wallkey = String(format: "key_wallpaper_for_page_%d", self.iPageIndex)
        if let paperData = UserDefaults.standard.value(forKey: wallkey) {
            if let papername = paperData as? String{
                if papername.lowercased().hasPrefix("http"){
                    return papername //目前只有动态壁纸才有http类型
                }
                else if isRightAblumFile(papername){
                    return papername
                }
            }
        }
//3、充电屏保
        if let batteryUrl = getBatteryUrl(){
            return batteryUrl
        }
        
        return nil
    }
    
    @objc func doShowSaver(){
        func removeSaverView(_ saverImgView:UIView){
            for perView in saverImgView.subviews{
                perView.removeFromSuperview()
            }
            saverImgView.removeFromSuperview()
        }
//将App隐掉，当前壁纸切换为屏保，
//或者简单点直接在最顶层显示一个屏保
    
        var idefault = 1//默认自定义屏保
        if let ilast = UserDefaults.standard.value(forKey: "aiScreen.saverMore.iflag") as? Int{
            idefault = ilast
        }
        if idefault >= 2{
            if let lastSaver = self.view.viewWithTag(1198){
                removeSaverView(lastSaver)
            }
            
            if 2 == idefault{
                removeBatteryAnimate() //屏保时关闭充电动画
                //翻页时钟\有声翻页时钟
                showFoldTimerSaver(idefault)
            }else if 3 == idefault{
                removeBatteryAnimate()
                //脉动时钟\有声脉动时钟
                showLEDTimerSaver(idefault)
            }else if 4 == idefault{
                removeBatteryAnimate()
                //无尽星空
                showStarsOverlaySaver(idefault)
            }else{
                showScreenSaver() //循环判断
            }
        }
        else if let saveUrlStr = getSaverUrl() {
            if let lastSaver = self.view.viewWithTag(1198){
                removeSaverView(lastSaver)
            }
            let saverImgView = UIImageView(frame: CGRect(x: 0, y: 0, width: screen_W, height: screen_H))
            self.view.addSubview(saverImgView)
            saverImgView.contentMode = .scaleAspectFill
            saverImgView.clipsToBounds = true
            saverImgView.tag = 1198
            saverImgView.layer.opacity = 0
//3种情况：列表http类型动态壁纸，相册类动态壁纸：file://xxx.gif、aiScreen.pCache.album.gif
            let lowUrl = saveUrlStr.lowercased()
            if lowUrl.hasPrefix("file://"){
//相册Gif图片地址
                if let imgUrl = URL(string: saveUrlStr){
                    if let imgData = NSData(contentsOf: imgUrl){
                        saverImgView.image = UIImage.sd_image(withGIFData: imgData as Data)
                        self.hideTopbar = true
                        self.setNeedsStatusBarAppearanceUpdate()
                        UIView.animate(withDuration: 1.75, delay: 0.25,options: [.curveEaseInOut]) {
                            saverImgView.layer.opacity = 1
                        } completion: { finished in
                            self.hideTopbar = true
                            self.setNeedsStatusBarAppearanceUpdate()
                            self.removeBatteryAnimate() //屏保时关闭充电动画
                            if 1 == idefault{
                                self.showSaverTimer(saverImgView)
                            }
                        }
                    }
                    else{
                        removeSaverView(saverImgView)
                        self.showScreenSaver() //循环判断
                    }
                }
            }else{
//http或aiScreen.pCache.album.gif
                saverImgView.loadImageFrom(imageurl: saveUrlStr,And: nil) { [weak self] (picUrl) in
                    if picUrl != nil{ //屏保动画加载成功
                        self?.hideTopbar = true
                        self?.setNeedsStatusBarAppearanceUpdate()
                        UIView.animate(withDuration: 1.75, delay: 0.25,options: [.curveEaseInOut]) {
                            saverImgView.layer.opacity = 1
                        } completion: { finished in
                            self?.hideTopbar = true
                            self?.setNeedsStatusBarAppearanceUpdate()
                            self?.removeBatteryAnimate()
                            if 1 == idefault{
                                self?.showSaverTimer(saverImgView)
                            }
                        }
                    }else{//加载失败则继续轮循
                        removeSaverView(saverImgView)
                        self?.showScreenSaver()
                    }
                }
            }
            
            let tapSaver = UITapGestureRecognizer(target: self, action: #selector(removeScreenSaver))
            saverImgView.addGestureRecognizer(tapSaver)
            saverImgView.isUserInteractionEnabled = true
            self.hideTopbar = false
            self.setNeedsStatusBarAppearanceUpdate()
        }else{
            showScreenSaver() //循环判断
        }
    }
    
    func showSaverTimer(_ saverImgView:UIView){
//在saverImgView顶部，有刘海(灵动岛的)左右角加个时钟 左侧周日 1-20,右侧 20:30(但刘海的宽度不知道)，老机型则模仿出一个刘海显示
//简单点，在底部中心画一半圆显示 时间/星期/日期(农历)
        func beginTimer(){
            if clockTimer == nil{
                clockTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { [weak self](timer) in
                    //                    self?.freshSaverTime(timer)
                                        self?.showSaverTimer(saverImgView)
                                    })
//                Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(freshSaverTime), userInfo: "1", repeats: true)
                if let curTimer = clockTimer {
                    RunLoop.main.add(curTimer, forMode: .common)
                    curTimer.fire() //马上触发，不然显示会慢1秒
                }
            }
        }
        if let bottomCalender = saverImgView.viewWithTag(1800){
            let calender = Calendar(identifier: .gregorian)
            let comps = calender.dateComponents([.month,.day,.weekday,.hour,.minute,.second], from: Date())
            if let weakLabel = bottomCalender.viewWithTag(1801) as? UILabel{
                if let weekday = comps.weekday{
                    let iweak = weekday - 1
                    let weekArr = ["周日","周一","周二","周三","周四","周五","周六"]
                    weakLabel.text = weekArr[iweak]
                }
            }
            if let dateLabel = bottomCalender.viewWithTag(1802) as? UILabel{
                if let iDay = comps.day,let iMon = comps.month,let iYear = comps.year{
                    dateLabel.text = String(format: "%d/%02d/%02d", iYear,iMon,iDay)
                }
            }
            
            if let hourLabel = bottomCalender.viewWithTag(1803) as? UILabel{
                if let iHour = comps.hour,let iMin = comps.minute,let iSec = comps.second{
                    hourLabel.text = String(format: "%02d:%02d:%02d", iHour,iMin,iSec)
                }
            }
            
        }else{
            let circleW = 100.0
            let bottomCalender = UIView(frame: CGRect(x: screen_W/2 - circleW/2, y: screen_H, width: circleW, height: circleW))
            saverImgView.addSubview(bottomCalender)
            bottomCalender.layer.cornerRadius = circleW/2
            bottomCalender.layer.borderWidth = 0.25
            bottomCalender.layer.borderColor = UIColor.white.withAlphaComponent(0.5).cgColor
            bottomCalender.backgroundColor = prjTitleColor.withAlphaComponent(0.5)
            bottomCalender.tag = 1800
            
            let weakLabel = UILabel(frame: CGRect(x: 0, y: 1, width: circleW, height: 12))
            bottomCalender.addSubview(weakLabel)
            weakLabel.textAlignment = .center
            weakLabel.font = .systemFont(ofSize: 9)
            weakLabel.tag = 1801
            let dateLabel = UILabel(frame: CGRect(x: 0, y: 13, width: circleW, height: 11))
            bottomCalender.addSubview(dateLabel)
            dateLabel.textAlignment = .center
            dateLabel.font = .systemFont(ofSize: 9)
            dateLabel.tag = 1802
            let hourLabel = UILabel(frame: CGRect(x: 0, y: 24, width: circleW, height: 15))
            bottomCalender.addSubview(hourLabel)
            hourLabel.textAlignment = .center
            hourLabel.font = UIFont(name: "Courier", size: 13)//等宽字体
            hourLabel.tag = 1803
            
            let calender = Calendar(identifier: .gregorian)
            let comps = calender.dateComponents([.year,.month,.day,.weekday,.hour,.minute,.second], from: Date())
            if let weekday = comps.weekday{
                let iweek = weekday - 1
                let weekArr = ["周日","周一","周二","周三","周四","周五","周六"]
                weakLabel.text = weekArr[iweek]
            }
            if let iHour = comps.hour,let iMin = comps.minute,let iSec = comps.second{
                hourLabel.text = String(format: "%02d:%02d:%02d", iHour,iMin,iSec)
            }
            if let iDay = comps.day,let iMon = comps.month,let iYear = comps.year{
                dateLabel.text = String(format: "%d/%02d/%02d", iYear,iMon,iDay)
            }
            
            UIView.animate(withDuration: 0.75, delay: 0.25) {
                bottomCalender.frame = CGRect(x: screen_W/2 - circleW/2, y: screen_H-40, width: circleW, height: circleW)
            } completion: { finish in
                beginTimer()
            }
        }
        
    }
    
//    @objc func freshSaverTime(_ timer:Timer){
//        if let saveImgView = self.view.viewWithTag(1198){
//            if let userInfo = timer.userInfo as? String{
//                if "1" == userInfo{ //底部日期时间
//                    showSaverTimer(saveImgView)
//                }else if "2" == userInfo{ //foldTimer
//                    showFoldTimerSaver(2)
//                }else if "3" == userInfo{ //ledTimer
//                    showLEDTimerSaver(3)
//                }
//            }
//        }
//    }
    
    func showFoldTimerSaver(_ iType:Int){
        func beginTimer(){
            if clockTimer == nil{
                clockTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { [weak self](timer) in
//                    self?.freshSaverTime(timer)
                    self?.showFoldTimerSaver(iType)
                })
//                Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(freshSaverTime), userInfo: String(iType), repeats: true)
                if let curTimer = clockTimer {
                    RunLoop.main.add(curTimer, forMode: .common)
                    curTimer.fire() //马上触发，不然显示会慢1秒
                }
            }
        }
        
        func getLastColor()->UIColor?{
            if let lastValue = UserDefaults.standard.value(forKey: "pickColor.foldtimer.ikey") as? Int{
                let pickColors: [UIColor] = [#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1),
                                             #colorLiteral(red: 1, green: 0.5411764706, blue: 0.5019607843, alpha: 1), #colorLiteral(red: 1, green: 0.09019607843, blue: 0.2666666667, alpha: 1),
                                             #colorLiteral(red: 0.7254901961, green: 0.9647058824, blue: 0.7921568627, alpha: 1), #colorLiteral(red: 0, green: 0.9019607843, blue: 0.462745098, alpha: 1),
                                             #colorLiteral(red: 0.9176470588, green: 0.5019607843, blue: 0.9882352941, alpha: 1), #colorLiteral(red: 0.8352941176, green: 0, blue: 0.9764705882, alpha: 1),
                                             #colorLiteral(red: 1, green: 1, blue: 0.5529411765, alpha: 1), #colorLiteral(red: 1, green: 0.8392156863, blue: 0, alpha: 1),
                                             #colorLiteral(red: 0.7019607843, green: 0.5333333333, blue: 1, alpha: 1), #colorLiteral(red: 0.3843137255, green: 0, blue: 0.9176470588, alpha: 1),
                                             #colorLiteral(red: 1, green: 0.8196078431, blue: 0.5019607843, alpha: 1), #colorLiteral(red: 1, green: 0.568627451, blue: 0, alpha: 1),
                                             #colorLiteral(red: 0.5490196078, green: 0.6196078431, blue: 1, alpha: 1), #colorLiteral(red: 0, green: 0.568627451, blue: 0.9176470588, alpha: 1),
                                             #colorLiteral(red: 1, green: 0.6196078431, blue: 0.5019607843, alpha: 1), #colorLiteral(red: 1, green: 0.2392156863, blue: 0, alpha: 1),
                                             #colorLiteral(red: 0.5019607843, green: 0.8470588235, blue: 1, alpha: 1), #colorLiteral(red: 0.5176470588, green: 1, blue: 1, alpha: 1),
                                             #colorLiteral(red: 0.4745098039, green: 0.3333333333, blue: 0.2823529412, alpha: 1), #colorLiteral(red: 0.3058823529, green: 0.2039215686, blue: 0.1803921569, alpha: 1)] //22个
                if lastValue>=0 && lastValue < pickColors.count{
                    return pickColors[lastValue]
                }
            }
            return nil
        }
        
        func showColorPicker(on rootView:UIView?){
            let bgView = UIView(frame: CGRect(x: 0, y: 0, width: screen_W, height: screen_H))
            rootView?.addSubview(bgView)
            let tapSaver = UITapGestureRecognizer(target: self, action: #selector(removeColorPicker))
            bgView.addGestureRecognizer(tapSaver)
    
            let pickColors: [UIColor] = [#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1),
                                         #colorLiteral(red: 1, green: 0.5411764706, blue: 0.5019607843, alpha: 1), #colorLiteral(red: 1, green: 0.09019607843, blue: 0.2666666667, alpha: 1),
                                         #colorLiteral(red: 0.7254901961, green: 0.9647058824, blue: 0.7921568627, alpha: 1), #colorLiteral(red: 0, green: 0.9019607843, blue: 0.462745098, alpha: 1),
                                         #colorLiteral(red: 0.9176470588, green: 0.5019607843, blue: 0.9882352941, alpha: 1), #colorLiteral(red: 0.8352941176, green: 0, blue: 0.9764705882, alpha: 1),
                                         #colorLiteral(red: 1, green: 1, blue: 0.5529411765, alpha: 1), #colorLiteral(red: 1, green: 0.8392156863, blue: 0, alpha: 1),
                                         #colorLiteral(red: 0.7019607843, green: 0.5333333333, blue: 1, alpha: 1), #colorLiteral(red: 0.3843137255, green: 0, blue: 0.9176470588, alpha: 1),
                                         #colorLiteral(red: 1, green: 0.8196078431, blue: 0.5019607843, alpha: 1), #colorLiteral(red: 1, green: 0.568627451, blue: 0, alpha: 1),
                                         #colorLiteral(red: 0.5490196078, green: 0.6196078431, blue: 1, alpha: 1), #colorLiteral(red: 0, green: 0.568627451, blue: 0.9176470588, alpha: 1),
                                         #colorLiteral(red: 1, green: 0.6196078431, blue: 0.5019607843, alpha: 1), #colorLiteral(red: 1, green: 0.2392156863, blue: 0, alpha: 1),
                                         #colorLiteral(red: 0.5019607843, green: 0.8470588235, blue: 1, alpha: 1), #colorLiteral(red: 0.5176470588, green: 1, blue: 1, alpha: 1),
                                         #colorLiteral(red: 0.4745098039, green: 0.3333333333, blue: 0.2823529412, alpha: 1), #colorLiteral(red: 0.3058823529, green: 0.2039215686, blue: 0.1803921569, alpha: 1)] //22个
            let pickHeight = 218.0 //4*42 + 5*10
            let pickWidth = 322.0 //6*42+7*10
            let pickView = UIView(frame: CGRect(x: 0, y: screen_H, width: pickWidth, height: pickHeight))
            bgView.addSubview(pickView)
            pickView.backgroundColor = .systemBackground.withAlphaComponent(0.5)
            pickView.setShadow(shadowColor: prjTitleColor, offset: CGSize(width: 1, height: 1), opacity: 0.65, radius: 5)
            
            let iJG = 10.0 //行间距
            var iTop = 10.0
            var iLeft = 10.0
            let iBtnW = 42.0
            var iCount = 0
            for _ in 0 ..< 4{ //4行*6列
                for _ in 0 ..< 6{
                    let btn = UIButton(frame: CGRect(x: iLeft, y: iTop, width: iBtnW, height: iBtnW))
                    pickView.addSubview(btn)
                    btn.backgroundColor = pickColors[iCount]
                    btn.setShadow(shadowColor: prjTitleColor, offset: CGSize(width: 1, height: 1), opacity: 0.25, radius: iBtnW/2)
                    btn.tag = iCount+1
                    btn.addActionWithBlock { [weak self](sender) in
                        let iTag = sender.tag - 1
                        if iTag>=0 && iTag<pickColors.count{
                            let aColor = pickColors[iTag]
                            if let bgView = self?.view.viewWithTag(1198){
                                if let foldItem_Hour = bgView.viewWithTag(1811) as? YYFoldClockItem{
                                    foldItem_Hour.textColor = aColor
                                }
                                if let foldItem_Minute = bgView.viewWithTag(1812) as? YYFoldClockItem{
                                    foldItem_Minute.textColor = aColor
                                }
                                if let foldItem_Second = bgView.viewWithTag(1813) as? YYFoldClockItem{
                                    foldItem_Second.textColor = aColor
                                }
                                UserDefaults.standard.setValue(iTag, forKey: "pickColor.foldtimer.ikey")
                                UserDefaults.standard.synchronize()
                            }
                        }
                    }
                    iLeft = iLeft + iBtnW + iJG
                    iCount = iCount + 1
                    if iCount>=pickColors.count{
                        break
                    }
                }
                iTop = iTop + iBtnW + iJG
                iLeft = 10.0
            }
            UIView.animate(withDuration: 0.25, delay: 0) {
                pickView.frame = CGRect(x: 0, y: screen_H - pickHeight - 20, width: pickWidth, height: pickHeight)
            }
        }

        if let bgView = self.view.viewWithTag(1198){
            if let lastValue = UserDefaults.standard.value(forKey: "playvoice.foldtimer.ikey") as? Int{
                if 1 == lastValue {
                    self.doPlay()
                }
            }
            let calender = Calendar(identifier: .gregorian)
            let comps = calender.dateComponents([.weekday,.month,.day,.hour,.minute,.second], from: Date())
            if let label_day_week = bgView.viewWithTag(1810) as? UILabel{
                if let imonth = comps.month,let iday = comps.day,let weekday = comps.weekday{
                    let iweak = weekday - 1
                    let weekArr = ["SUNDAY","MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"]
                    label_day_week.text = String(format: "%02d.%02d %@",imonth,iday,weekArr[iweak]) //"11.18 MONDAY"
                }
            }
            if let foldItem_Hour = bgView.viewWithTag(1811) as? YYFoldClockItem{
                if let hour = comps.hour{
                    foldItem_Hour.time = hour
                }
            }
            if let foldItem_Minute = bgView.viewWithTag(1812) as? YYFoldClockItem{
                if let minute = comps.minute{
                    foldItem_Minute.time = minute
                }
            }
            if let foldItem_Second = bgView.viewWithTag(1813) as? YYFoldClockItem{
                if let second = comps.second{
                    foldItem_Second.time = second
                }
            }
        }else{
            let saverImgView = UIView(frame: CGRect(x: 0, y: 0, width: screen_W, height: screen_H))
            self.view.addSubview(saverImgView)
            saverImgView.tag = 1198
            saverImgView.layer.opacity = 0
            saverImgView.backgroundColor = .systemGroupedBackground
            
            let h_JG = 35.0
            let clockHeight = (screen_H - 70) / 5
            let clockWidth = (screen_H - 70) / 5 / 0.72
            let midX = screen_W/2 - clockWidth/2
            let midY = screen_H/2 - clockHeight/2
            let foldView = UIView(frame: CGRect(x: midX, y: midY - h_JG - clockHeight - 35.0, width: clockWidth, height: clockHeight*3+2*h_JG+35.0))
            saverImgView.addSubview(foldView)
            //need.update 长按显示修改颜色选择器
            
            let calender = Calendar(identifier: .gregorian)
            let comps = calender.dateComponents([.weekday,.month,.day,.hour,.minute,.second], from: Date())
            
            let label_day_week = UILabel(frame: CGRect(x: 0, y: 0, width: clockWidth, height: 20))
            foldView.addSubview(label_day_week)
            label_day_week.font = UIFont(name: "Courier", size: 16)
            label_day_week.textColor = .white.withAlphaComponent(0.7)
            if let imonth = comps.month,let iday = comps.day,let weekday = comps.weekday{
                let iweak = weekday - 1
                let weekArr = ["SUNDAY","MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"]
                label_day_week.text = String(format: "%02d.%02d %@",imonth,iday,weekArr[iweak]) //"11.18 MONDAY"
            }
            label_day_week.textAlignment = .center
            label_day_week.tag = 1810
            
            let timeFont = UIFont(name: "DINAlternate-Bold", size: CGFloat(clockHeight) * 0.65)
            
            let lastItemColor = getLastColor()
            if let foldItem_Hour = YYFoldClockItem.init(frame: CGRect(x: 0, y: 35 , width: clockWidth, height: clockHeight), andJG: 10){
                foldView.addSubview(foldItem_Hour)
                foldItem_Hour.tag = 1811
                foldItem_Hour.type = .XLClockItemTypeHour
                foldItem_Hour.font = timeFont
                if let hour = comps.hour{
                    foldItem_Hour.time = hour
                }
                foldItem_Hour.setBack(UIColor.clear, andLineColor: UIColor.black)
                foldItem_Hour.setTextBack(UIColor("1c1c1c")) //文本背景色，不适合透明色，会看到后面未翻页的数字
                if let lastColor = lastItemColor{
                    foldItem_Hour.textColor = lastColor
                }
            }
            if let foldItem_Minute = YYFoldClockItem.init(frame: CGRect(x: 0, y:35 + clockHeight+h_JG , width: clockWidth, height: clockHeight), andJG: 10){
                foldView.addSubview(foldItem_Minute)
                foldItem_Minute.tag = 1812
                foldItem_Minute.type = .XLClockItemTypeMinute
                foldItem_Minute.font = timeFont
                if let minute = comps.minute{
                    foldItem_Minute.time = minute
                }
                foldItem_Minute.setBack(UIColor.clear, andLineColor: UIColor.black)
                foldItem_Minute.setTextBack(UIColor("1c1c1c"))
                if let lastColor = lastItemColor{
                    foldItem_Minute.textColor = lastColor
                }
            }
            if let foldItem_Second = YYFoldClockItem.init(frame: CGRect(x: 0, y:35 + clockHeight*2+h_JG*2 , width: clockWidth, height: clockHeight), andJG: 10){
                foldView.addSubview(foldItem_Second)
                foldItem_Second.tag = 1813
                foldItem_Second.type = .XLClockItemTypeSecond
                foldItem_Second.font = timeFont
                if let second = comps.second{
                    foldItem_Second.time = second
                }
                foldItem_Second.setBack(UIColor.clear, andLineColor: UIColor.black)
                foldItem_Second.setTextBack(UIColor("1c1c1c"))
                if let lastColor = lastItemColor{
                    foldItem_Second.textColor = lastColor
                }
            }
            let btnTop = foldView.frame.maxY + 20
            let btnConfig = UIButton(frame: CGRect(x: screen_W - 15 - 31, y: btnTop, width: 31, height: 30))
            saverImgView.addSubview(btnConfig)
            btnConfig.setImage(UIImage(named: "saver_config"), for: .normal)
            btnConfig.addActionWithBlock { [weak self](sender) in
//显示颜色选择器
                showColorPicker(on: self?.view)
            }
            var voiceName = "saver_voice_open"
            if let lastValue = UserDefaults.standard.value(forKey: "playvoice.foldtimer.ikey") as? Int{
                if 1 == lastValue{
                    self.initPlayer("vol_folder", "wav")//默认开启声音
                }else{
                    voiceName = "saver_voice_close"
                }
            }else{
                UserDefaults.standard.set(1, forKey: "playvoice.foldtimer.ikey")
                UserDefaults.standard.synchronize()
                self.initPlayer("vol_folder", "wav")//默认开启声音
            }
            let btnVoice = UIButton(frame: CGRect(x: screen_W - 20 - 31*2 , y: btnTop, width: 31, height: 30))
            saverImgView.addSubview(btnVoice)
            btnVoice.setImage(UIImage(named: voiceName), for: .normal)
            btnVoice.addActionWithBlock { [weak self](sender) in
                if let lastValue = UserDefaults.standard.value(forKey: "playvoice.foldtimer.ikey") as? Int{
                    if 1 == lastValue{
                        UserDefaults.standard.set(0, forKey: "playvoice.foldtimer.ikey")
                        sender.setImage(UIImage(named: "saver_voice_close"), for: .normal)
                        self?.freePlay()
                    }else{
                        UserDefaults.standard.set(1, forKey: "playvoice.foldtimer.ikey")
                        sender.setImage(UIImage(named: "saver_voice_open"), for: .normal)
                        self?.initPlayer("vol_folder", "wav")
                    }
                    UserDefaults.standard.synchronize()
                }
            }
            
            let tapSaver = UITapGestureRecognizer(target: self, action: #selector(removeScreenSaver))
            saverImgView.addGestureRecognizer(tapSaver)
            self.hideTopbar = true
            self.setNeedsStatusBarAppearanceUpdate()
            UIView.animate(withDuration: 0.75, delay: 0.25,options: [.curveEaseInOut]) {
                saverImgView.layer.opacity = 1
            } completion: { [weak self](finished) in
                self?.hideTopbar = true
                self?.setNeedsStatusBarAppearanceUpdate()
                self?.removeBatteryAnimate()
                beginTimer()
            }
        }
    
    }
    
    func showLEDTimerSaver(_ iType:Int){
        func beginTimer(){
            if clockTimer == nil{
                clockTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { [weak self](timer) in
                    //                    self?.freshSaverTime(timer)
                                        self?.showLEDTimerSaver(iType)
                                    })
//                Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(freshSaverTime), userInfo: String(iType), repeats: true)
                if let curTimer = clockTimer {
                    RunLoop.main.add(curTimer, forMode: .common)
                    curTimer.fire() //马上触发，不然显示会慢1秒
                }
            }
        }
        
        func getLastColor()->UIColor?{
            if let lastValue = UserDefaults.standard.value(forKey: "pickColor.ledtimer.ikey") as? Int{
                let pickColors: [UIColor] = [#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1),
                                             #colorLiteral(red: 1, green: 0.5411764706, blue: 0.5019607843, alpha: 1), #colorLiteral(red: 1, green: 0.09019607843, blue: 0.2666666667, alpha: 1),
                                             #colorLiteral(red: 0.7254901961, green: 0.9647058824, blue: 0.7921568627, alpha: 1), #colorLiteral(red: 0, green: 0.9019607843, blue: 0.462745098, alpha: 1),
                                             #colorLiteral(red: 0.9176470588, green: 0.5019607843, blue: 0.9882352941, alpha: 1), #colorLiteral(red: 0.8352941176, green: 0, blue: 0.9764705882, alpha: 1),
                                             #colorLiteral(red: 1, green: 1, blue: 0.5529411765, alpha: 1), #colorLiteral(red: 1, green: 0.8392156863, blue: 0, alpha: 1),
                                             #colorLiteral(red: 0.7019607843, green: 0.5333333333, blue: 1, alpha: 1), #colorLiteral(red: 0.3843137255, green: 0, blue: 0.9176470588, alpha: 1),
                                             #colorLiteral(red: 1, green: 0.8196078431, blue: 0.5019607843, alpha: 1), #colorLiteral(red: 1, green: 0.568627451, blue: 0, alpha: 1),
                                             #colorLiteral(red: 0.5490196078, green: 0.6196078431, blue: 1, alpha: 1), #colorLiteral(red: 0, green: 0.568627451, blue: 0.9176470588, alpha: 1),
                                             #colorLiteral(red: 1, green: 0.6196078431, blue: 0.5019607843, alpha: 1), #colorLiteral(red: 1, green: 0.2392156863, blue: 0, alpha: 1),
                                             #colorLiteral(red: 0.5019607843, green: 0.8470588235, blue: 1, alpha: 1), #colorLiteral(red: 0.5176470588, green: 1, blue: 1, alpha: 1),
                                             #colorLiteral(red: 0.4745098039, green: 0.3333333333, blue: 0.2823529412, alpha: 1), #colorLiteral(red: 0.3058823529, green: 0.2039215686, blue: 0.1803921569, alpha: 1)] //22个
                if lastValue>=0 && lastValue < pickColors.count{
                    return pickColors[lastValue]
                }
            }
            return nil
        }
        
        func showColorPicker(on rootView:UIView?){
            let bgView = UIView(frame: CGRect(x: 0, y: 0, width: screen_W, height: screen_H))
            rootView?.addSubview(bgView)
            let tapSaver = UITapGestureRecognizer(target: self, action: #selector(removeColorPicker))
            bgView.addGestureRecognizer(tapSaver)
    
            let pickColors: [UIColor] = [#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1),
                                         #colorLiteral(red: 1, green: 0.5411764706, blue: 0.5019607843, alpha: 1), #colorLiteral(red: 1, green: 0.09019607843, blue: 0.2666666667, alpha: 1),
                                         #colorLiteral(red: 0.7254901961, green: 0.9647058824, blue: 0.7921568627, alpha: 1), #colorLiteral(red: 0, green: 0.9019607843, blue: 0.462745098, alpha: 1),
                                         #colorLiteral(red: 0.9176470588, green: 0.5019607843, blue: 0.9882352941, alpha: 1), #colorLiteral(red: 0.8352941176, green: 0, blue: 0.9764705882, alpha: 1),
                                         #colorLiteral(red: 1, green: 1, blue: 0.5529411765, alpha: 1), #colorLiteral(red: 1, green: 0.8392156863, blue: 0, alpha: 1),
                                         #colorLiteral(red: 0.7019607843, green: 0.5333333333, blue: 1, alpha: 1), #colorLiteral(red: 0.3843137255, green: 0, blue: 0.9176470588, alpha: 1),
                                         #colorLiteral(red: 1, green: 0.8196078431, blue: 0.5019607843, alpha: 1), #colorLiteral(red: 1, green: 0.568627451, blue: 0, alpha: 1),
                                         #colorLiteral(red: 0.5490196078, green: 0.6196078431, blue: 1, alpha: 1), #colorLiteral(red: 0, green: 0.568627451, blue: 0.9176470588, alpha: 1),
                                         #colorLiteral(red: 1, green: 0.6196078431, blue: 0.5019607843, alpha: 1), #colorLiteral(red: 1, green: 0.2392156863, blue: 0, alpha: 1),
                                         #colorLiteral(red: 0.5019607843, green: 0.8470588235, blue: 1, alpha: 1), #colorLiteral(red: 0.5176470588, green: 1, blue: 1, alpha: 1),
                                         #colorLiteral(red: 0.4745098039, green: 0.3333333333, blue: 0.2823529412, alpha: 1), #colorLiteral(red: 0.3058823529, green: 0.2039215686, blue: 0.1803921569, alpha: 1)] //22个
            let pickHeight = 218.0 //4*42 + 5*10
            let pickWidth = 322.0 //6*42+7*10
            let pickView = UIView(frame: CGRect(x: 0, y: screen_H, width: pickWidth, height: pickHeight))
            bgView.addSubview(pickView)
            pickView.backgroundColor = .systemBackground.withAlphaComponent(0.5)
            pickView.setShadow(shadowColor: prjTitleColor, offset: CGSize(width: 1, height: 1), opacity: 0.65, radius: 5)
            
            let iJG = 10.0 //行间距
            var iTop = 10.0
            var iLeft = 10.0
            let iBtnW = 42.0
            var iCount = 0
            for _ in 0 ..< 4{ //4行*6列
                for _ in 0 ..< 6{
                    let btn = UIButton(frame: CGRect(x: iLeft, y: iTop, width: iBtnW, height: iBtnW))
                    pickView.addSubview(btn)
                    btn.backgroundColor = pickColors[iCount]
                    btn.setShadow(shadowColor: prjTitleColor, offset: CGSize(width: 1, height: 1), opacity: 0.25, radius: iBtnW/2)
                    btn.tag = iCount+1
                    btn.addActionWithBlock { [weak self](sender) in
                        let iTag = sender.tag - 1
                        if iTag>=0 && iTag<pickColors.count{
                            let aColor = pickColors[iTag]
                            if let bgView = self?.view.viewWithTag(1198){
                                if let hourLabel = bgView.viewWithTag(1821) as? UILabel{
                                    hourLabel.textColor = aColor
                                }
                                if let minuteLabel = bgView.viewWithTag(1822) as? UILabel{
                                    minuteLabel.textColor = aColor
                                }
                                UserDefaults.standard.setValue(iTag, forKey: "pickColor.ledtimer.ikey")
                                UserDefaults.standard.synchronize()
                            }
                        }
                    }
                    iLeft = iLeft + iBtnW + iJG
                    iCount = iCount + 1
                    if iCount>=pickColors.count{
                        break
                    }
                }
                iTop = iTop + iBtnW + iJG
                iLeft = 10.0
            }
            UIView.animate(withDuration: 0.25, delay: 0) {
                pickView.frame = CGRect(x: 0, y: screen_H - pickHeight - 20, width: pickWidth, height: pickHeight)
            }
        }
        
        if let bgView = self.view.viewWithTag(1198){
            if let lastValue = UserDefaults.standard.value(forKey: "playvoice.ledtimer.ikey") as? Int{
                if 1 == lastValue {
                    self.doPlay()
                }
            }

            if let lay_dot_1 = led_layer_dot_1,let lay_dot_2 = led_layer_dot_2{
                if let lastState = lay_dot_1.value(forKey: "dot_is_highlight") as? Bool{
                    if lastState {
                        lay_dot_1.setValue(false, forKey: "dot_is_highlight")
                        lay_dot_1.backgroundColor = UIColor("1c1c1c").cgColor
                        lay_dot_2.backgroundColor = UIColor("1c1c1c").cgColor
                    }else{
                        lay_dot_1.setValue(true, forKey: "dot_is_highlight")
                        if let lastItemColor = getLastColor(){
                            lay_dot_1.backgroundColor = lastItemColor.cgColor
                            lay_dot_2.backgroundColor = lastItemColor.cgColor
                        }else{
                            lay_dot_1.backgroundColor = UIColor.white.cgColor
                            lay_dot_2.backgroundColor = UIColor.white.cgColor
                        }
                    }
                }else{
                    lay_dot_1.setValue(true, forKey: "dot_is_highlight")
                    if let lastItemColor = getLastColor(){
                        lay_dot_1.backgroundColor = lastItemColor.cgColor
                        lay_dot_2.backgroundColor = lastItemColor.cgColor
                    }else{
                        lay_dot_1.backgroundColor = UIColor.white.cgColor
                        lay_dot_2.backgroundColor = UIColor.white.cgColor
                    }
                }
            }
      
            let calender = Calendar(identifier: .gregorian)
            let comps = calender.dateComponents([.weekday,.month,.day,.hour,.minute], from: Date())
            
            if let hourLabel = bgView.viewWithTag(1821) as? UILabel{
                if let hour = comps.hour{
                    hourLabel.text = String(format: "%02d", hour)
                }
            }
            if let minuteLabel = bgView.viewWithTag(1822) as? UILabel{
                if let minute = comps.minute{
                    minuteLabel.text = String(format: "%02d", minute)
                }
            }
            if let label_day_week = bgView.viewWithTag(1823) as? UILabel{
                if let weekday = comps.weekday,let imonth = comps.month,let iday = comps.day{
                    let iweek = weekday - 1
                    let weekArr = ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"]
                    label_day_week.text = String(format: "%02d.%02d %@",imonth,iday,weekArr[iweek])
                }
            }
        }else{
            let saverImgView = UIView(frame: CGRect(x: 0, y: 0, width: screen_W, height: screen_H))
            self.view.addSubview(saverImgView)
            saverImgView.tag = 1198
            saverImgView.layer.opacity = 0
            saverImgView.backgroundColor = .systemGroupedBackground
            
            let dotWidth = 35.0
            let clockHeight = (screen_H - dotWidth - 2*screen_H*0.15) / 2  //2*screen_H*0.15顶部和底部各留screen_H*0.15间隔
            let clockWidth = clockHeight
            let midX = screen_W/2
            let dotY = screen_H/2 - dotWidth/2
            
            led_layer_dot_1 = CALayer()
            if let lay_dot_1 = led_layer_dot_1{
                lay_dot_1.frame = CGRect(x: midX-dotWidth-15, y: dotY, width: dotWidth, height: dotWidth)
                lay_dot_1.cornerRadius = 5
                lay_dot_1.masksToBounds = true
                saverImgView.layer.addSublayer(lay_dot_1)
                lay_dot_1.setValue(true, forKey: "dot_is_highlight")
            }
            
            led_layer_dot_2 = CALayer()
            if let lay_dot_2 = led_layer_dot_2{
                lay_dot_2.frame = CGRect(x: midX+15, y: dotY, width: dotWidth, height: dotWidth)
                lay_dot_2.cornerRadius = 5
                lay_dot_2.masksToBounds = true
                saverImgView.layer.addSublayer(lay_dot_2)
            }
            
            let calender = Calendar(identifier: .gregorian)
            let comps = calender.dateComponents([.weekday,.month,.day,.hour,.minute], from: Date())
            let hourLabel = UILabel(frame: CGRect(x: midX-clockWidth/2, y: dotY-clockHeight, width: clockWidth, height: clockHeight))
            hourLabel.font = UIFont(name: "LED", size: CGFloat(clockHeight) * 0.75)
            hourLabel.textAlignment = .center
            saverImgView.addSubview(hourLabel)
            hourLabel.tag = 1821
            if let hour = comps.hour{
                hourLabel.text = String(format: "%02d", hour)
            }

            let minuteLabel = UILabel(frame: CGRect(x: midX-clockWidth/2, y: dotY+35, width: clockWidth, height: clockHeight))
            minuteLabel.font = UIFont(name: "LED", size: CGFloat(clockHeight) * 0.75)
            minuteLabel.textAlignment = .center
            saverImgView.addSubview(minuteLabel)
            minuteLabel.tag = 1822
            if let minute = comps.minute{
                minuteLabel.text = String(format: "%02d", minute)
            }

            let label_day_week = UILabel(frame: CGRect(x: 0, y: dotY - clockHeight - 20, width: screen_W, height: 20))
            saverImgView.addSubview(label_day_week)
            label_day_week.font = UIFont(name: "Oxanium-SemiBold", size: 16)
            label_day_week.textColor = .white.withAlphaComponent(0.7)
            label_day_week.text = "01.01   MONDAY"
            label_day_week.textAlignment = .center
            label_day_week.tag = 1823
            if let weekday = comps.weekday,let imonth = comps.month,let iday = comps.day{
                let iweek = weekday - 1
                let weekArr = ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"]
                label_day_week.text = String(format: "%02d.%02d %@",imonth,iday,weekArr[iweek])
            }
            
            if let lastItemColor = getLastColor(){
                led_layer_dot_1?.backgroundColor = lastItemColor.cgColor
                led_layer_dot_2?.backgroundColor = lastItemColor.cgColor
                hourLabel.textColor = lastItemColor
                minuteLabel.textColor = lastItemColor
            }else{
                led_layer_dot_1?.backgroundColor = UIColor.white.cgColor
                led_layer_dot_2?.backgroundColor = UIColor.white.cgColor
                hourLabel.textColor = .white
                minuteLabel.textColor = .white
            }
            
            let btnTop = minuteLabel.frame.maxY + 20
            let btnConfig = UIButton(frame: CGRect(x: screen_W - 15 - 31, y: btnTop, width: 31, height: 30))
            saverImgView.addSubview(btnConfig)
            btnConfig.setImage(UIImage(named: "saver_config"), for: .normal)
            btnConfig.addActionWithBlock { [weak self](sender) in
//显示颜色选择器
                showColorPicker(on: self?.view)
            }
            var voiceName = "saver_voice_open"
            if let lastValue = UserDefaults.standard.value(forKey: "playvoice.ledtimer.ikey") as? Int{
                if 1 == lastValue{
                    self.initPlayer("vol_led", "mp3")//默认开启声音
                }else{
                    voiceName = "saver_voice_close"
                }
            }else{
                UserDefaults.standard.set(1, forKey: "playvoice.ledtimer.ikey")
                UserDefaults.standard.synchronize()
                self.initPlayer("vol_led", "mp3")//默认开启声音
            }
            
            let btnVoice = UIButton(frame: CGRect(x: screen_W - 20 - 31*2 , y: btnTop, width: 31, height: 30))
            saverImgView.addSubview(btnVoice)
            btnVoice.setImage(UIImage(named: voiceName), for: .normal)
            btnVoice.addActionWithBlock { [weak self](sender) in
                if let lastValue = UserDefaults.standard.value(forKey: "playvoice.ledtimer.ikey") as? Int{
                    if 1 == lastValue{
                        UserDefaults.standard.set(0, forKey: "playvoice.ledtimer.ikey")
                        sender.setImage(UIImage(named: "saver_voice_close"), for: .normal)
                        self?.freePlay()
                    }else{
                        UserDefaults.standard.set(1, forKey: "playvoice.ledtimer.ikey")
                        sender.setImage(UIImage(named: "saver_voice_open"), for: .normal)
                        self?.initPlayer("vol_led", "mp3")
                    }
                    UserDefaults.standard.synchronize()
                }
            }
            
            let tapSaver = UITapGestureRecognizer(target: self, action: #selector(removeScreenSaver))
            saverImgView.addGestureRecognizer(tapSaver)
            self.hideTopbar = true
            self.setNeedsStatusBarAppearanceUpdate()
            UIView.animate(withDuration: 0.75, delay: 0.25,options: [.curveEaseInOut]) {
                saverImgView.layer.opacity = 1
            } completion: { [weak self](finished) in
                self?.hideTopbar = true
                self?.setNeedsStatusBarAppearanceUpdate()
                self?.removeBatteryAnimate()
                beginTimer()
            }
        }
    }
    
    func showStarsOverlaySaver(_ iType:Int){
        let saverImgView = StarsOverlay(frame: CGRect(x: 0, y: 0, width: screen_W, height: screen_H))
        view.addSubview(saverImgView)
        saverImgView.tag = 1198
        saverImgView.layer.opacity = 0
        saverImgView.backgroundColor = .black
        let tapSaver = UITapGestureRecognizer(target: self, action: #selector(removeScreenSaver))
        saverImgView.addGestureRecognizer(tapSaver)
        self.hideTopbar = true
        self.setNeedsStatusBarAppearanceUpdate()
        UIView.animate(withDuration: 0.75, delay: 0.25,options: [.curveEaseInOut]) {
            saverImgView.layer.opacity = 1
        } completion: { [weak self](finished) in
            self?.hideTopbar = true
            self?.setNeedsStatusBarAppearanceUpdate()
            self?.removeBatteryAnimate()
        }
    }
    
    func stopClockTimer(){
        if clockTimer != nil{
            clockTimer?.invalidate()
            clockTimer = nil
        }
    }
    
    @objc func removeScreenSaver(_ tap:UITapGestureRecognizer){
        if let sender = tap.view{
            self.freePlay()
            self.stopClockTimer()
            UIView.animate(withDuration: 1.25, delay: 0.25,options: [.curveEaseInOut]) {
                sender.layer.opacity = 0
            } completion: { finished in
                self.freePlay()
                self.stopClockTimer()
                self.stopScreenSave()
                sender.removeFromSuperview()
                
                self.hideTopbar = false
                self.setNeedsStatusBarAppearanceUpdate()
                self.showScreenSaver() //循环判断
                self.showBatteryOrNot()
            }
        }
    }
    
    @objc func removeColorPicker(_ tap:UITapGestureRecognizer){
        if let sender = tap.view{
            UIView.animate(withDuration: 0.25, delay: 0,options: [.curveEaseInOut]) {
                sender.layer.opacity = 0
            } completion: { finished in
                for perView in sender.subviews{
                    perView.removeFromSuperview()
                }
                sender.removeFromSuperview()
            }
        }
    }
}

extension ViewController{
//MARK: - 系统菜单
    @objc func tapPopMenuBg(){
        if let bgView = view.viewWithTag(1590){
            bgView.removeFromSuperview()
        }
    }
    
    func showPopmenu(){
        self.hideTopbar = false
        self.setNeedsStatusBarAppearanceUpdate()
        tapPopMenuBg()
        let popBgView = UIView(frame: CGRect(x: 0, y: 0, width: screen_W, height: screen_H))
        view.addSubview(popBgView)
        popBgView.tag = 1590
        popBgView.backgroundColor = .systemBackground.withAlphaComponent(0.5)
        let tapPopbg = UITapGestureRecognizer(target: self, action: #selector(tapPopMenuBg))
        popBgView.addGestureRecognizer(tapPopbg)
        
        let topSpace = UIDevice.ui_navigationFullHeight()
        let rowHeight = 44.0
        let menuWidth = 200.0
        let menuView = UIView(frame: CGRect(x: screen_W - 15 - menuWidth, y: topSpace, width: menuWidth, height: rowHeight * 7))
        popBgView.addSubview(menuView)
        menuView.backgroundColor = .systemGroupedBackground
        menuView.setShadow(shadowColor: prjTitleColor, offset: CGSize(width: 3, height: 3), opacity: 0.5, radius: 10)
        
//默认显示屏保
        let icoHeight = 24.0
        let icoLeft = 15.0
        let btnLeft = 50.0
        var iTop = 0.0
        let ico_saver = UIImageView(frame: CGRect(x: icoLeft, y: rowHeight/2 - icoHeight/2, width: icoHeight, height: icoHeight) )
        menuView.addSubview(ico_saver)
        ico_saver.image = UIImage(named: "menu_saver@2x")
        let btnFont:UIFont = .systemFont(ofSize: 15)
        let btn_saver = UIButton(frame: CGRect(x: btnLeft, y: iTop, width: menuWidth - btnLeft, height: rowHeight))
        menuView.addSubview(btn_saver)
        btn_saver.setTitle("启用屏保", for: .normal)
        btn_saver.setTitleColor(.label, for: .normal)
        btn_saver.titleLabel?.font = btnFont
//            btn_saver.titleLabel?.textAlignment = .left//无效
        btn_saver.contentHorizontalAlignment = .left //这个可以标题左对齐
        btn_saver.addActionWithBlock { [weak self](sender) in
            Vibrations.selection.vibrate()
            self?.tapPopMenuBg()
            self?.showScreenSaverSelectionDlg()
        }
//选用屏保
        iTop = iTop + rowHeight
        let layer_select = CALayer()
        menuView.layer.addSublayer(layer_select)
        layer_select.frame = CGRect(x: btnLeft, y: iTop-0.5, width: menuWidth, height: 0.5)
        layer_select.backgroundColor = UIColor.separator.withAlphaComponent(0.5).cgColor
        let ico_select = UIImageView(frame: CGRect(x: 15, y: iTop+rowHeight/2-icoHeight/2, width: icoHeight, height: icoHeight) )
        menuView.addSubview(ico_select)
        ico_select.image = UIImage(named: "menu_selectsaver@2x.png")
        ico_select.contentMode = .center
        let btn_select = UIButton(frame: CGRect(x: btnLeft, y: iTop, width: menuWidth - btnLeft, height: rowHeight))
        menuView.addSubview(btn_select)
        btn_select.setTitle("选择屏保", for: .normal)
        btn_select.setTitleColor(.label, for: .normal)
        btn_select.titleLabel?.font = btnFont
        btn_select.contentHorizontalAlignment = .left
        btn_select.addActionWithBlock { [weak self](sender) in
            Vibrations.light.vibrate()
            self?.tapPopMenuBg()
            self?.showMoreSaverSelectDlg()
        }
//充电特效
        iTop = iTop + rowHeight
        let layer_0 = CALayer()
        menuView.layer.addSublayer(layer_0)
        layer_0.frame = CGRect(x: 0, y: iTop - 0.5, width: menuWidth, height: 0.5)
        layer_0.backgroundColor = UIColor.separator.cgColor
        let ico_battery = UIImageView(frame: CGRect(x: icoLeft, y: iTop + rowHeight/2 - icoHeight/2, width: icoHeight, height: icoHeight) )
        menuView.addSubview(ico_battery)
        ico_battery.image = UIImage(named: "menu_battery@2x.png")
        let btn_battery = UIButton(frame: CGRect(x: btnLeft, y: iTop, width: menuWidth - btnLeft, height: rowHeight))
        menuView.addSubview(btn_battery)
        btn_battery.setTitle("充电特效", for: .normal)
        btn_battery.setTitleColor(.label, for: .normal)
        btn_battery.titleLabel?.font = btnFont
        btn_battery.contentHorizontalAlignment = .left
        btn_battery.addActionWithBlock { [weak self](sender) in
            Vibrations.light.vibrate()
            self?.tapPopMenuBg()
            self?.showBatterySelectionDlg()
        }
//清缓存
        iTop = iTop + rowHeight
        let layer_1 = CALayer()
        menuView.layer.addSublayer(layer_1)
        layer_1.frame = CGRect(x: 0, y: iTop - 0.5, width: menuWidth, height: 0.5)
        layer_1.backgroundColor = UIColor.separator.cgColor
        let ico_clear = UIImageView(frame: CGRect(x: icoLeft, y: iTop + rowHeight/2 - icoHeight/2, width: icoHeight, height: icoHeight) )
        menuView.addSubview(ico_clear)
        ico_clear.image = UIImage(named: "menu_clear@2x.png")
        let btn_clear = UIButton(frame: CGRect(x: btnLeft, y: iTop, width: menuWidth - btnLeft, height: rowHeight))
        menuView.addSubview(btn_clear)
        btn_clear.setTitle("清除缓存", for: .normal)
        btn_clear.setTitleColor(.label, for: .normal)
        btn_clear.titleLabel?.font = btnFont
        btn_clear.contentHorizontalAlignment = .left
        btn_clear.addActionWithBlock { [weak self] (sender) in
            Vibrations.light.vibrate()
            self?.tapPopMenuBg()
            self?.showClearCacheDlg()
        }
//帮助
        iTop = iTop + rowHeight
        let layer_2 = CALayer()
        menuView.layer.addSublayer(layer_2)
        layer_2.frame = CGRect(x: 0, y: iTop-0.5, width: menuWidth, height: 0.5)
        layer_2.backgroundColor = UIColor.separator.cgColor
        let ico_learn = UIImageView(frame: CGRect(x: 15, y: iTop+rowHeight/2-icoHeight/2, width: icoHeight, height: icoHeight) )
        menuView.addSubview(ico_learn)
        ico_learn.image = UIImage(named: "menu_learn@2x.png")
        let btn_learn = UIButton(frame: CGRect(x: btnLeft, y: iTop, width: menuWidth - btnLeft, height: rowHeight))
        menuView.addSubview(btn_learn)
        btn_learn.setTitle("aiScreen帮助", for: .normal)
        btn_learn.setTitleColor(.label, for: .normal)
        btn_learn.titleLabel?.font = btnFont
        btn_learn.contentHorizontalAlignment = .left
        btn_learn.addActionWithBlock { [weak self] (sender) in
            Vibrations.light.vibrate()
            self?.tapPopMenuBg()
            self?.showLearnPage()
        }
//关于我们
        iTop = iTop + rowHeight
        let layer_3 = CALayer()
        menuView.layer.addSublayer(layer_3)
        layer_3.frame = CGRect(x: btnLeft, y: iTop-0.5, width: menuWidth, height: 0.5)
        layer_3.backgroundColor = UIColor.separator.withAlphaComponent(0.5).cgColor
        let ico_about = UIImageView(frame: CGRect(x: 15, y: iTop+rowHeight/2-icoHeight/2, width: icoHeight, height: icoHeight) )
        menuView.addSubview(ico_about)
        ico_about.image = UIImage(named: "menu_about@2x.png")
        let btn_about = UIButton(frame: CGRect(x: btnLeft, y: iTop, width: menuWidth - btnLeft, height: rowHeight))
        menuView.addSubview(btn_about)
        btn_about.setTitle("关于我们", for: .normal)
        btn_about.setTitleColor(.label, for: .normal)
        btn_about.titleLabel?.font = btnFont
        btn_about.contentHorizontalAlignment = .left
        btn_about.addActionWithBlock { [weak self] (sender) in
            Vibrations.light.vibrate()
            self?.tapPopMenuBg()
            self?.showAboutDlg()
        }
//刷新(防止图标加载不全时，重新加载App图标)
        iTop = iTop + rowHeight
        let layer_4 = CALayer()
        menuView.layer.addSublayer(layer_4)
        layer_4.frame = CGRect(x: 0, y: iTop-0.5, width: menuWidth, height: 0.5)
        layer_4.backgroundColor = UIColor.separator.cgColor
        let ico_fresh = UIImageView(frame: CGRect(x: 15, y: iTop+rowHeight/2-icoHeight/2, width: icoHeight, height: icoHeight) )
        menuView.addSubview(ico_fresh)
        ico_fresh.image = UIImage(named: "menu_refresh@2x.png")
        let btn_fresh = UIButton(frame: CGRect(x: btnLeft, y: iTop, width: menuWidth - btnLeft, height: rowHeight))
        menuView.addSubview(btn_fresh)
        btn_fresh.setTitle("刷新Ai桌面", for: .normal)
        btn_fresh.setTitleColor(.label, for: .normal)
        btn_fresh.titleLabel?.font = btnFont
        btn_fresh.contentHorizontalAlignment = .left
        btn_fresh.addActionWithBlock { [weak self] (sender) in
            Vibrations.light.vibrate()
            self?.tapPopMenuBg()
            self?.refreshAppUI()
        }
    }
    
    func showScreenSaverSelectionDlg(){
        var idefault = 0
        if let ilast = UserDefaults.standard.value(forKey: "aiScreen.saver.iflag") as? Int{
            idefault = ilast
        }
        self.alertSheetMessage("启用屏保设置", message: "请选屏保启用模式", selections: ["空闲5s后显示屏保","空闲10s后显示屏保","空闲15s后显示屏保","空闲30s后显示屏保","空闲60s后显示屏保","不显示屏保"],iRed: idefault) { [weak self](actionIndex) in
            UserDefaults.standard.setValue(actionIndex, forKey: "aiScreen.saver.iflag")
            UserDefaults.standard.synchronize()
//如果当前正处充电状态，则切换动画>
            if actionIndex != idefault{
                if actionIndex == 5{
                    self?.view.showToast("屏保已关闭")
                    self?.stopScreenSave()
                }else{
                    self?.view.showToast("已开启空闲自动屏保")
                    self?.showScreenSaver()
                }
            }
        }
    }
    
    func showMoreSaverSelectDlg(){
        var idefault = 9 //默认未选任何一个
        if let ilast = UserDefaults.standard.value(forKey: "aiScreen.saverMore.iflag") as? Int{
            idefault = ilast
        }
        self.alertSheetMessage("更多屏保选用", message: "请选用要展示的屏保动效", selections: ["屏保壁纸中设定的屏保","屏保壁纸中设定的屏保(+时钟)","翻页时钟屏保","脉动时钟屏保","无尽星空屏保"],iRed: idefault) { [weak self](actionIndex) in
//如果当前正处充电状态，则切换动画>
            if actionIndex<2{
//如果走壁纸设定的屏保，则须确保已设置
                if let _ = self?.getSaverUrl() {
                    UserDefaults.standard.setValue(actionIndex, forKey: "aiScreen.saverMore.iflag")
                    UserDefaults.standard.synchronize()
                }else{
                    self?.alertMessage("未选择自定义屏保", message: "您尚未在『屏保壁纸』中设置屏保，现在去设置么") {[weak self] in
                        self?.showWallPaperSelectDlg()
                    }
                }
            }else{
                UserDefaults.standard.setValue(actionIndex, forKey: "aiScreen.saverMore.iflag")
                UserDefaults.standard.synchronize()
            }
        }
    }
    
    func showBatterySelectionDlg(){
        var idefault = 1
        if let ilast = UserDefaults.standard.value(forKey: "aiScreen.battery.animation.i") as? Int{
            idefault = ilast
        }
        self.alertSheetMessage("充电动效选择", message: "请选择充电状态时显示的动效", selections: ["无","进度条","烟花","步步高","地涌金莲","波浪","水晶泡泡"],iRed: idefault) { [weak self] (actionIndex) in
            UserDefaults.standard.setValue(actionIndex, forKey: "aiScreen.battery.animation.i")
            UserDefaults.standard.synchronize()
//如果当前正处充电状态，则切换动画>
            if actionIndex != idefault{
                self?.removeBatteryAnimate()
                self?.showBatteryAnimation(actionIndex)
            }
        }

    }
    
    func showBatteryAnimation(_ iAnimate:Int?){
        if (batteryState == .charging) || (batteryState == .full){
            if let iaction = iAnimate{
                switch iaction{
                case 1:
                    showBatteryProgress() //进度动画
                case 2:
                    showBatteryFireworksAnimate()
                case 3:
                    showwBatteryRocketAnimate()
                case 4:
                    showwBatteryGoldOutAnimate()
                case 5:
                    showwBatteryWaveAnimate()
                case 6:
                    showwBatteryPaopaoAnimate()
                default://0不显示
                    removeBatteryAnimate()
                }
            }else{
                //nil显示默认进度条
                showBatteryProgress()
            }
        }else{//非充电模式下清除
            removeBatteryAnimate()
        }
    }
//MARK: -清缓存s
    func showClearCacheDlg(){
        let cachSize = HLUniversalFunc.sharedInstance.fileSizeOfAllCache()
        let strTitle = String(format: "%.2fM", cachSize)
        self.alertMessage("清除缓存", message: "确定要清除缓存么？",okTitle: "清除缓存\(strTitle)",otherTitle: "深度清理",cancelTitle: "取消",iRed: 2) {[weak self] in
            Vibrations.selection.vibrate()
            HLUniversalFunc.sharedInstance.clearAllCache(deepClean: false)
            self?.view.showToast("已清除缓存\(strTitle)")
        } midBlock: {[weak self] in
            Vibrations.selection.vibrate()
            HLUniversalFunc.sharedInstance.clearAllCache(deepClean: true)
            self?.view.showToast("缓存清除完毕!")
        }
    }
    
    func showLearnPage(){
//        openSchemeUrl("https://note.youdao.com/s/BCrLmxnh", nil) //用safari打开
//        let webVC = WebViewController()
//        self.present(webVC, animated: true)
//        webVC.loadUrlStr(urlstr: "https://note.youdao.com/s/BCrLmxnh",title: "我的Ai桌面-使用教程") //在App内部加载教程，会形成较大的缓存数据
//下一版显示：使用教程、制作锁屏特效教程、制作gif动态壁纸及屏保教程
        self.alertSheetMessage("教程", message: "aiScreen相关教程", selection_1: "aiScreen-使用教程", selection_2: "aiScrenn-锁屏特效壁纸教程") {
            HLUniversalFunc.openSchemeUrl("https://note.youdao.com/s/BCrLmxnh", nil)
        } midBlock: {
            HLUniversalFunc.openSchemeUrl("https://note.youdao.com/s/BFfc3yay", nil)
        }

    }
    
    func showAboutDlg(){
        func repeatAnimate(){
            UIView.animate(withDuration: 10.0, delay: 0.5) {
                moveLabel.frame = CGRect(x: 0, y: -95, width: screen_W, height: 100)
            } completion: { finied in
                moveLabel.frame = CGRect(x: 0, y: 25, width: screen_W, height: 100)
                repeatAnimate()
            }
        }
        
        let popBgView = UIView(frame: CGRect(x: 0, y: 0, width: screen_W, height: screen_H))
        view.addSubview(popBgView)
        popBgView.tag = 1590
        popBgView.backgroundColor = .systemBackground.withAlphaComponent(0.75)
        let tapPopbg = UITapGestureRecognizer(target: self, action: #selector(tapPopMenuBg))
        popBgView.addGestureRecognizer(tapPopbg)
        
        var iTop = 160.0
        let logoView = UIImageView(frame: CGRect(x: screen_W/2-128/2, y: iTop, width: 128, height: 128))
        popBgView.addSubview(logoView)
        logoView.image = UIImage(named: "AppIcon")
        logoView.layer.cornerRadius = 15
        logoView.clipsToBounds = true //imageview的圆角需要这个
        
        iTop = iTop + 145
        let titleLabel = UILabel(frame: CGRect(x: 0, y: iTop, width: screen_W, height: 20))
        popBgView.addSubview(titleLabel)
        titleLabel.text = "aiScreen（我的Ai桌面）"
        titleLabel.textAlignment = .center
        titleLabel.font = .systemFont(ofSize: 16)
        titleLabel.textColor = .label
        iTop = iTop+20
        let versionLabel = UILabel(frame: CGRect(x: 0, y: iTop, width: screen_W, height: 20))
        popBgView.addSubview(versionLabel)
        versionLabel.text = "Ver 1.1"
        if let infoDict = Bundle.main.infoDictionary{
            if let version = infoDict["CFBundleShortVersionString"] as? String{
                if let buildVer = infoDict["CFBundleVersion"] as? String{
                    versionLabel.text = String(format: "Ver \(version).\(buildVer)")
                }
            }
        }
        versionLabel.textAlignment = .center
        versionLabel.font = .systemFont(ofSize: 12)
        versionLabel.textColor = .secondaryLabel
        
        iTop = iTop+20
        let beianLabel = UILabel(frame: CGRect(x: 0, y: iTop, width: screen_W, height: 20))
        popBgView.addSubview(beianLabel)
        beianLabel.textAlignment = .center
        beianLabel.font = .systemFont(ofSize: 14)
        beianLabel.textColor = .label.withAlphaComponent(0.75)
        beianLabel.text = "浙ICP备2021025253号-4A"
        
        iTop = iTop+20
        let homeButton = UIButton(frame: CGRect(x: 0, y: iTop, width: screen_W, height: 30))
        popBgView.addSubview(homeButton)
        homeButton.setTitle("联系我们", for:.normal)
        homeButton.setTitleColor(.secondaryLabel, for: .normal)
        homeButton.titleLabel?.font = .systemFont(ofSize: 12)
        homeButton.showUnderlineStyle()
        homeButton.addActionWithBlock { sender in
            HLUniversalFunc.openSchemeUrl("http://apk.hhkyj.com/", nil)
        }
        
        iTop = iTop+30
        let btn_xy = UIButton(frame: CGRect(x: screen_W/2 - 200/2, y: iTop, width: 200, height: 30))
        popBgView.addSubview(btn_xy)
        btn_xy.setTitle("用户协议   >", for: .normal)
        btn_xy.setTitleColor(.link.withAlphaComponent(0.6), for: .normal)
        btn_xy.titleLabel?.font = .systemFont(ofSize: 12)
        btn_xy.addActionWithBlock { sender in
            HLUniversalFunc.openSchemeUrl("http://apk.hhkyj.com/terms.html", nil)
        }
        
        iTop = iTop+30
        let btn_ys = UIButton(frame: CGRect(x: screen_W/2 - 200/2, y: iTop, width: 200, height: 30))
        popBgView.addSubview(btn_ys)
        btn_ys.setTitle("隐私政策   >", for: .normal)
        btn_ys.setTitleColor(.link.withAlphaComponent(0.6), for: .normal)
        btn_ys.titleLabel?.font = .systemFont(ofSize: 12)
        btn_ys.addActionWithBlock { sender in
            HLUniversalFunc.openSchemeUrl("http://apk.hhkyj.com/privacy.html", nil)
        }
        
        iTop = iTop+35
        let backView = UIView(frame: CGRect(x: 0, y: iTop, width: screen_W, height: 30))
        popBgView.addSubview(backView)
        backView.clipsToBounds = true
        let moveLabel = UILabel(frame: CGRect(x: 0, y: 0, width: screen_W, height: 100))
        backView.addSubview(moveLabel)
        moveLabel.text = String(format: "一键开启App&小程序\n隐藏伪装App图标\n动态壁纸\n充电屏保\n锁屏特效")
        moveLabel.textAlignment = .center
        moveLabel.numberOfLines = 0
//        moveLabel.backgroundColor = .blue
        moveLabel.font = .systemFont(ofSize: 14)
        UIView.animate(withDuration: 10.0, delay: 0.5) {
            moveLabel.frame = CGRect(x: 0, y: -95, width: screen_W, height: 100)
        } completion: { finished in
            moveLabel.frame = CGRect(x: 0, y: 25, width: screen_W, height: 100)
            repeatAnimate()
        }
    }
    
    func refreshAppUI(){
//如果当前壁纸也是http，则也更新
        if iPageIndex<pageWallList.count{
            let wallkey = String(format: "key_wallpaper_for_page_%d", iPageIndex)
            if let paperData = UserDefaults.standard.value(forKey: wallkey) {
                if let papername = paperData as? String{
                    if papername.hasPrefix("http"){
                        let tmpBkView = UIImageView(image: UIImage(named: "defaltWall@2x.jpeg"))
                        pageWallList[iPageIndex].insertSubview(tmpBkView, at: 0) //加载网络图片前，先显示默认图，然后加载完成后再过渡到壁纸
                        tmpBkView.frame = CGRect(x: 0, y: 0, width: screen_W, height: screen_H)
                        pageWallList[iPageIndex].loadImageFrom(imageurl: papername,And: nil) { [weak self](picUrl) in
                            if let self = self,picUrl == nil{ //加载网络图片出错
                                self.pageWallList[self.iPageIndex].image = UIImage(named: "defaltWall@2x.jpeg")
                            }
                            UIView.animate(withDuration: 0.75, delay: 0,options: [.curveEaseInOut]) {
                                tmpBkView.layer.opacity = 0
                            } completion: { finised in
                                tmpBkView.isHidden = true
                                tmpBkView.image = nil
                                tmpBkView.removeFromSuperview()
                                
                            }
                        }
                    }
                }
            }
        }
        
        if icoLabelList.count > iPageIndex{
            let icoApps = icoLabelList[iPageIndex]
//重新刷新各App图标，以免有的加载未完成
            for perIco in icoApps{
                perIco.relaodAppIco()
            }
            self.view.showToast("当前桌面已刷新")
            self.tapBackView()
        }
    }
}

//MARK: -LeftBar
extension ViewController{
    func onTapLeftBar(sender:UIView){
        Vibrations.medium.vibrate()
        self.tapBackView()
        if let _ = self.view.viewWithTag(1518){
            cancelLeftBarItems(duration: 0.5) {
                self.tapBackView()
            }
        }else{
            if bloom_soundid != 0 {
                AudioServicesPlaySystemSound(bloom_soundid)
            }
            stopScreenSave()
            
            let centerPos = sender.center
            let bloomView = UIView(frame: CGRect(x: 0, y: 0, width: screen_W, height: screen_H))
            self.view.insertSubview(bloomView, belowSubview: sender)
            bloomView.tag = 1518
            func createBloomButton(with iR:CGFloat,iBtnSize:CGSize,fromArc:Int,toArc:Int,titles:[String]? = nil,imgNames:[String]? = nil){
                var iCount = 0
                if let titleArr = titles{
                    iCount = titleArr.count
                }else if let imgArr = imgNames{
                    iCount = imgArr.count
                    
                    var btnArr:[UIButton] = []
                    for i in 0 ..< imgArr.count {
                        let btn = UIButton(frame: CGRect(x: 0, y: 0, width: iBtnSize.width, height: iBtnSize.height))
                        bloomView.addSubview(btn)
                        btn.center = sender.center
                        btn.imageView?.contentMode = .center
                        btn.setImage(UIImage(named: imgArr[i]), for: .normal)
                        btn.backgroundColor = .white
                        btn.tag = 1510 + i
                        btn.setShadow(shadowColor: .cyan, offset: CGSize(width: 1, height: 1), opacity: 0.8, radius: iBtnSize.width/2)
                        btn.addActionWithBlock { [weak self](sender) in
                            self?.pressLeftbarItem(sender)
                        }
                        btnArr.append(btn)
                        
                    }
                    let perArc = (toArc - fromArc) / (iCount-1)
                    var beginArc = fromArc
                    UIView.animate(withDuration: 0.5, delay: 0,options: [.curveEaseInOut]) {
                        for i in 0 ..< btnArr.count {
                            let x = centerPos.x + iR * cos(Double(beginArc) * Double.pi/180)
                            let y = centerPos.y + iR * sin(Double(beginArc) * Double.pi/180)
                            btnArr[i].frame = CGRect(x: x, y: y, width: iBtnSize.width, height: iBtnSize.height)
                            beginArc = beginArc + perArc
                        }
                    }
                }
            }
            createBloomButton(with: 100,iBtnSize:CGSize(width: 40, height: 40),fromArc: -75, toArc: 75,imgNames: ["bloom_add@2x.png","bloom_edit@2x.png","bloom_align@2x.png","bloom_paper@2x.png"])
        }
    }
    
    func cancelLeftBarItems(duration:CGFloat=0.25,completion:os_block_t?=nil){
        if let bloomView = self.view.viewWithTag(1518){
            if fold_soundid != 0 {
                AudioServicesPlaySystemSound(fold_soundid)
            }
            UIView.animate(withDuration: duration, delay: 0) {
                for perView in bloomView.subviews{
                    perView.layer.opacity = 0
                    if let leftbar = self.leftPopBar{
                        perView.center = leftbar.center
                    }
                }
            } completion: { finish in
                for perView in bloomView.subviews{
                    perView.removeFromSuperview()
                }
                bloomView.removeFromSuperview()
                completion?()
            }
        }else{
            completion?()
        }
    }
    
    func pressLeftbarItem(_ sender:UIButton){
        if select_soundid != 0 {
            AudioServicesPlaySystemSound(select_soundid)
        }
        Vibrations.light.vibrate()
        cancelLeftBarItems {
            let iTag = sender.tag
            if 1510 == iTag{//add
                self.pressAddButton(self.leftPopBar)
//------test.begin
//                HLIdleOperationQueue.sharedObject().interval = 200;
//                HLIdleOperationQueue.sharedObject().add {
//                    print("----before.waiting.1")
//                }
//                HLIdleOperationQueue.sharedObject().add {
//                    print("----before.waiting.2")
//                }
//测试deinit
//                let tmpVC = ScreenSaverVC()
//                tmpVC.modalPresentationStyle = .fullScreen
//                self.present(tmpVC, animated: true)
                
//测试animateToCrush
//                if let tmpView = self.view.viewWithTag(1900){
//                    tmpView.removeFromSuperview()
//                }
//                else if let image = self.view.snapshot2Image(with: CGRect(x: 100, y: 100, width: 200, height: 200)){
//                    let imageView = UIImageView(frame: CGRect(x: screen_W-200, y: screen_H-400, width: 200, height: 200))
//                    self.view.addSubview(imageView)
//                    imageView.image = image
//                    imageView.tag = 1900
//                    imageView.animateToCrush(crushSize: CGSize(width: 20, height: 20),xSmall: -5.0,xBig: 5.0, duration: 0.75,delayTime: 2.0)
//                }
//-------test.end
            }else if 1511 == iTag{//modi
                self.doLongTapIcoLabel(nil)
                self.shakeOtherApps()
                Vibrations.success.vibrate()
            }else if 1512 == iTag{//对齐
                if self.icoLabelList.count > self.iPageIndex && self.icoLabelList[self.iPageIndex].count>0{
                    self.doAutoMatrix(isBottom: true)
                }else{
                    Vibrations.error.vibrate()
                    self.view.showToast("您尚未添加快捷项到Ai桌面")
                }
            }else{//壁纸
                self.showWallPaperSelectDlg(self.leftPopBar)
            }
        }
    }
    
    func initLeftBar(){
        let backWidth = 40.0
        let backHeight = 82.0
        let btnWidth = 40.0
        let iLeft = 10.0
        let bottomSpace = max(UIDevice.ui_safeDistanceBottom(), 15) //iphone8下为0
        let maxHeight = 2*appHeight + bottomSpace + 20
        
        if leftPopBar == nil{
            let leftbar = UIView(frame: CGRect(x: -iLeft - backWidth, y: screen_H - maxHeight - backHeight, width: backWidth, height: backHeight))
            view.addSubview(leftbar)
            
            let topView = UIView(frame: CGRect(x: 0, y: 0, width: btnWidth, height: btnWidth))
            leftbar.addSubview(topView)
            topView.clipsToBounds = true
            
            let topCircle = UIButton(frame: CGRect(x: -btnWidth, y: 0, width: btnWidth*2, height: btnWidth*2))
            topView.addSubview(topCircle)
            topCircle.backgroundColor = .cyan.withAlphaComponent(0.65)
            topCircle.layer.cornerRadius = btnWidth
            topCircle.addActionWithBlock { [weak self](sender) in
                self?.onTapLeftBar(sender: leftbar)
            }
            topCircle.layer.borderWidth = 0.25
            topCircle.layer.borderColor = UIColor.separator.withAlphaComponent(0.75).cgColor
            let imgView_bat = UIImageView(frame: CGRect(x: iLeft, y: 8, width: 16, height: 16))
            topView.addSubview(imgView_bat)
            imgView_bat.image = UIImage(named: "leftbar_bat@2x.png")
            
            let batteryLabel = UILabel(frame: CGRect(x: iLeft, y: btnWidth/2, width: btnWidth-iLeft, height: btnWidth/2))
            topView.addSubview(batteryLabel)
            batteryLabel.textAlignment = .center
            
            let batText = String(format: "\(Int(batteryLevel>0 ? batteryLevel*100 : 0))%%")
            let batMutableString = NSMutableAttributedString(
                string: batText,
                attributes: [NSAttributedString.Key.font:UIFont.boldSystemFont(ofSize: 10),
                             NSAttributedString.Key.foregroundColor:UIColor.white])
            let range_1:NSRange = (batText as NSString).range(of:"%")
            batMutableString.addAttributes([NSAttributedString.Key.font:UIFont.systemFont(ofSize: 8)], range: range_1)
            batteryLabel.attributedText = batMutableString
            batteryLabel.tag = 1910
            
            let bottomView = UIView(frame: CGRect(x: 0, y: backHeight-btnWidth, width: btnWidth, height: btnWidth))
            leftbar.addSubview(bottomView)
            bottomView.clipsToBounds = true
            
            let bottomCircle = UIButton(frame: CGRect(x: -btnWidth, y: -btnWidth, width: btnWidth*2, height: btnWidth*2))
            bottomView.addSubview(bottomCircle)
            bottomCircle.backgroundColor = .cyan.withAlphaComponent(0.65)
            bottomCircle.layer.cornerRadius = btnWidth
            bottomCircle.addActionWithBlock { [weak self](sender) in
                self?.onTapLeftBar(sender: leftbar)
            }
            bottomCircle.layer.borderWidth = 0.25
            bottomCircle.layer.borderColor =  UIColor.separator.withAlphaComponent(0.75).cgColor
            
//            let imgView_date = UIImageView(frame: CGRect(x: iLeft+3, y: btnWidth/2-4, width: 12, height: 12))
//            bottomView.addSubview(imgView_date)
//            imgView_date.image = UIImage(named: "leftbar_date@2x.png")
            let weekLabel = UILabel(frame: CGRect(x: iLeft+3, y: btnWidth/2-4, width: 12, height: 12))
            bottomView.addSubview(weekLabel)
            weekLabel.textAlignment = .center
            weekLabel.font = .boldSystemFont(ofSize: 9)
            weekLabel.textColor = .white
            let calender = Calendar(identifier: .gregorian)
            let comps = calender.dateComponents([.weekday,.month,.day], from: Date())
            if let weekday = comps.weekday{
                let iweak = weekday - 1
                let weekArr = ["日","一","二","三","四","五","六"]
                weekLabel.text = weekArr[iweak]
            }
            weekLabel.tag = 1911
            
            let dateLabel = UILabel(frame: CGRect(x: iLeft, y: 0, width: btnWidth-iLeft, height: btnWidth/2))
            bottomView.addSubview(dateLabel)
            dateLabel.textAlignment = .center
            dateLabel.tag = 1912
//            let dateFormatter = DateFormatter()
//            dateFormatter.dateFormat = "dd/MM" // "yyyy-MM-dd HH:mm:ss"
//            let dateText = dateFormatter.string(from: Date()) // 将 Date 对象转换为字符串
//            let todate = dateFormatter.date(from: dateString) // 将字符串转换为 Date 对象
            if let iMonth = comps.month, let iDay = comps.day{
                let dateText = String(format: "%02d/%02d",iDay,iMonth)
                let myMutableString = NSMutableAttributedString(
                    string: dateText,
                    attributes: [NSAttributedString.Key.font:UIFont.boldSystemFont(ofSize: 10),
                                 NSAttributedString.Key.foregroundColor:UIColor.white])
                let range_2:NSRange = (dateText as NSString).range(of:"/11")
                myMutableString.addAttributes([NSAttributedString.Key.font:UIFont.systemFont(ofSize: 8)], range: range_2)
                dateLabel.attributedText = myMutableString
            }
            
            leftPopBar = leftbar
            UIView.animate(withDuration: 0.45, delay: 0.55,options: [.curveEaseInOut]) {
                leftbar.frame = CGRect(x: -iLeft, y: screen_H - maxHeight - backHeight, width: backWidth, height: backHeight)
            }
        }else{
//            UIView.animate(withDuration: 0.25, delay: 0) {
//                self.leftPopBar?.frame = CGRect(x: -iLeft - backWidth, y: screen_H - maxHeight - backHeight, width: backWidth, height: backHeight)
//            }
            
            if let batteryLabel = self.leftPopBar?.viewWithTag(1910) as? UILabel{
                let batText = String(format: "\(Int(batteryLevel>0 ? batteryLevel*100 : 0))%%")
                let batMutableString = NSMutableAttributedString(
                    string: batText,
                    attributes: [NSAttributedString.Key.font:UIFont.boldSystemFont(ofSize: 10),
                                 NSAttributedString.Key.foregroundColor:UIColor.white])
                let range_1:NSRange = (batText as NSString).range(of:"%")
                batMutableString.addAttributes([NSAttributedString.Key.font:UIFont.systemFont(ofSize: 8)], range: range_1)
                batteryLabel.attributedText = batMutableString
            }
            
            let calender = Calendar(identifier: .gregorian) //代表公历
            let comps = calender.dateComponents([.weekday,.month,.day], from: Date())
            if let weekLabel = self.leftPopBar?.viewWithTag(1911) as? UILabel{
                if let weekday = comps.weekday{
                    let iweak = weekday - 1
                    let weekArr = ["日","一","二","三","四","五","六"]
                    weekLabel.text = weekArr[iweak]
                }
            }
            if let dateLabel = self.leftPopBar?.viewWithTag(1912) as? UILabel{
                if let iDay = comps.day, let iMonth = comps.month{
                    let dateText = String(format: "%02d/%02d",iDay,iMonth)
                    let myMutableString = NSMutableAttributedString(
                        string: dateText,
                        attributes: [NSAttributedString.Key.font:UIFont.boldSystemFont(ofSize: 10),
                                     NSAttributedString.Key.foregroundColor:UIColor.white])
                    let range_2:NSRange = (dateText as NSString).range(of:"/11")
                    myMutableString.addAttributes([NSAttributedString.Key.font:UIFont.systemFont(ofSize: 8)], range: range_2)
                    dateLabel.attributedText = myMutableString
                }
            }
//如果屏保时需要显示电量则：
//            leftPopBar?.frame = CGRect(x: -iLeft - backWidth, y: screen_H - maxHeight - backHeight, width: backWidth, height: backHeight)
//            self.view.bringSubviewToFront(leftPopBar!)
//            UIView.animate(withDuration: 0.45, delay: 0.55,options: [.curveEaseInOut]) {
//                self.leftPopBar?.frame = CGRect(x: -iLeft, y: screen_H - maxHeight - backHeight, width: backWidth, height: backHeight)
//            }
        }
        if 0 == bloom_soundid {
            if let url = Bundle.main.url(forResource: "btn_bloom", withExtension: "caf"){
                AudioServicesCreateSystemSoundID(url as CFURL, &bloom_soundid)
            }
        }
        if 0 == fold_soundid{
            if let url = Bundle.main.url(forResource: "btn_fold", withExtension: "caf"){
                AudioServicesCreateSystemSoundID(url as CFURL, &fold_soundid)
            }
        }
        if 0 == select_soundid{
            if let url = Bundle.main.url(forResource: "btn_selected", withExtension: "caf"){
                AudioServicesCreateSystemSoundID(url as CFURL, &select_soundid)
            }
        }
    }
}

extension ViewController{
    func freePlay(){
        if _soundID != 0 {
            AudioServicesDisposeSystemSoundID(_soundID)
            AudioServicesRemoveSystemSoundCompletion(_soundID)
        }
        _soundID = 0
//        if player != nil {
//            self.player?.stop()
//            self.player = nil
//        }
    }
    
    func doPlay(){
        if _soundID != 0 {
            AudioServicesPlaySystemSound(_soundID)
        }
//        if self.player != nil {
//            self.player?.play()
//        }
    }
    
//    vol_folder,wav
    func initPlayer(_ voiceName:String,_ voiceExt:String) {
//        let path = Bundle.main.path(forResource: voiceName[soundIndex], ofType: "wav") //无法识别caf, but.wav/mp3.OK
//        let url = NSURL(fileURLWithPath: path!)
        guard let url = Bundle.main.url(forResource: voiceName, withExtension: voiceExt) else{
            return
        }
        AudioServicesCreateSystemSoundID(url as CFURL, &_soundID)
    }
}

extension ViewController{
//点击或按下爆炸特效
    private func showPressCirlceHeart(_ iType:Int,_ position:CGPoint){
//iType = 0点击屏幕,1长按屏幕，2删除App
        func doShow(){
            if let centerHeartLayer = pressHeartLayer{
                centerHeartLayer.beginTime = CACurrentMediaTime()//在0.2秒后设置birthrate=0,这个0.2秒的时间内，cell只生成一部分，并没有2000个全部完成。
                centerHeartLayer.birthRate = 1
                centerHeartLayer.emitterPosition = position
                var itime = 0.5
                if 1 == iType{
                    itime = 1.0
                }else if 2 == iType{
                    itime = 0.75
                }
                if 1 == iType{
                    centerHeartLayer.emitterSize = CGSize(width: 100, height: 100)
                }else if 0 == iType{
                    centerHeartLayer.emitterSize = CGSize(width: 50, height: 50)
                }else if 2 == iType{
                    centerHeartLayer.emitterSize = CGSize(width: 20, height: 20)
                }
                DispatchQueue.main.asyncAfter(deadline: .now() + itime) {[weak self] in
                    guard let strongSelf = self else {return}
                    strongSelf.pressHeartLayer?.birthRate = 0
                    strongSelf.pressHeartLayer?.removeFromSuperlayer()
                    strongSelf.pressHeartLayer = nil
                }
                DispatchQueue.main.asyncAfter(deadline: .now() + 1) {[weak self] in
                    guard self != nil else {return}
                    //            sender.isUserInteractionEnabled = true
                }
            }
        }
//        sender.isUserInteractionEnabled = false
        //设置时间参数
        if let _ = pressHeartLayer{
            doShow()
        }else{
            configPressCirlceHeart()
            doShow()
        }
    }
    
    private func configPressCirlceHeart(){
        func emitterCell(withImage image: UIImage) -> CAEmitterCell {
            //设置CAEmitterCell
            let cell = CAEmitterCell()
            //设置cell的内容
            cell.contents = image.cgImage // #imageLiteral(resourceName: "Heart_red").cgImage
            //设置周期时间
            cell.lifetime = 2.0
            //设置scale大小
            cell.scale = 0.05
//                cell.scaleRange = 0.05
            //设置粒子数
            cell.birthRate = 1000
            //设置scale的speed
            cell.scaleSpeed = -0.02
            //设置alpha的speed
            cell.alphaSpeed = -1
            //设置粒子的速度
            cell.velocity = 30
//            cell.velocityRange = 20
            cell.spin  = 2 * Double.pi
            cell.spinRange = 2 * Double.pi
            return cell
        }
        //设置centerHeartLayer
        pressHeartLayer = CAEmitterLayer()
        if let centerHeartLayer = pressHeartLayer{
            //设置发射源粒的形状
            centerHeartLayer.emitterShape = .circle
            //设置发射粒子的模式
            centerHeartLayer.emitterMode = .outline
            //设置渲染效果
            centerHeartLayer.renderMode = .unordered// .oldestFirst
            //设置发射源的位置
            centerHeartLayer.emitterPosition = CGPoint(x: screen_W/2, y: screen_H/2)
            //设置发射源的大小
            centerHeartLayer.emitterSize = CGSizeMake(50, 50)
            centerHeartLayer.birthRate = 0 //初始化先赋值为0，动效不会执行
            
            
            let cell_red = emitterCell(withImage: #imageLiteral(resourceName: "Heart_red"))
            let cell_blue = emitterCell(withImage: #imageLiteral(resourceName: "Heart_blue"))
            centerHeartLayer.emitterCells = [cell_red,cell_blue]
            self.view.layer.addSublayer(centerHeartLayer)
        }
    }
}

extension ViewController{
//MARK: - 默认启动项
//初始化：默认2个壁纸、默认引导App,
    func loadDefaultApp(){
        if let _ = UserDefaults.standard.value(forKey: "key.init.default.apps"){
            self.tapBackView()
        }else if hasIcoLabelInCurrentPage(){
            self.tapBackView()
        }else{
//            let sourceList = HLUniversalFunc.getArrFromJSONFile(forName: "default_apps")
            
        }
    }
    
    func showFuctionGuide(){
        
    }
}


